@box-kite/react 2.2.0 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.claude/rules/box-kite-rules.md +1 -1
  2. package/.claude/skills/box-kite/SKILL.md +1 -1
  3. package/.claude/skills/box-kite/references/components.md +3 -3
  4. package/.claude/skills/box-kite/references/styling.md +2 -1
  5. package/.cursor/rules/box-kite.mdc +1 -1
  6. package/AGENTS.md +1 -1
  7. package/BOX_AI_CONTEXT.md +95 -77
  8. package/BOX_KITE_AI_CONTEXT.md +95 -77
  9. package/README.md +1 -1
  10. package/client.cjs +1 -1
  11. package/client.mjs +61 -51
  12. package/components/dataGrid/components/dataGridBottomBarSelection.d.ts +7 -0
  13. package/components/dataGrid/components/dataGridColumnsPanel.d.ts +10 -0
  14. package/components/dataGrid/components/dataGridDetailRow.d.ts +3 -3
  15. package/components/dataGrid/components/dataGridGroupRow.d.ts +3 -3
  16. package/components/dataGrid/components/dataGridHeader.d.ts +6 -2
  17. package/components/dataGrid/components/dataGridRow.d.ts +3 -3
  18. package/components/dataGrid/contracts/dataGridContract.d.ts +13 -0
  19. package/components/dataGrid/gridNavigationContext.d.ts +7 -2
  20. package/components/dataGrid/models/columnModel.d.ts +2 -0
  21. package/components/dataGrid/models/columnVisibilityModel.d.ts +16 -2
  22. package/components/dataGrid/models/editModel.d.ts +6 -4
  23. package/components/dataGrid/models/exportModel.d.ts +1 -1
  24. package/components/dataGrid/models/gridModel.d.ts +60 -2
  25. package/components/dataGrid/models/groupRowModel.d.ts +2 -2
  26. package/components/dataGrid/models/headerCellModel.d.ts +10 -0
  27. package/components/dataGrid/models/localeText.d.ts +108 -0
  28. package/components/dataGrid/models/rangeModel.d.ts +2 -0
  29. package/components/dataGrid/models/rowModel.d.ts +1 -1
  30. package/components/dataGrid/useFilterDraft.d.ts +9 -0
  31. package/components/dataGrid.cjs +3 -3
  32. package/components/dataGrid.d.ts +1 -0
  33. package/components/dataGrid.mjs +1631 -1120
  34. package/components/semantics.d.ts +29 -29
  35. package/docs/components.md +1 -1
  36. package/docs/props.md +1 -1
  37. package/layer.cjs +1 -1
  38. package/layer.mjs +4 -1
  39. package/package.json +76 -46
  40. package/react/theme/theme.d.ts +5 -3
  41. package/utils/dataGrid/activeCellStore.d.ts +14 -0
  42. package/utils/dataGrid/filterDraftUtils.d.ts +19 -0
  43. package/utils/dataGrid/headerCellUtils.d.ts +50 -0
  44. package/components/dataGrid/components/dataGridTopBarContextMenu.d.ts +0 -6
@@ -726,7 +726,7 @@ so a change that was a jump becomes a transition with nothing animated by hand.
726
726
  | `viewTransitionName` | Names this element, so it animates _from where it was to where it is_ instead of being cross-faded with the page. A `<custom-ident>`, **not** dashed |
727
727
  | `viewTransitionClass` | A name shared by several elements, so `::view-transition-group(.card)` styles them together. Space-separated for more than one |
728
728
  | `Box.viewTransition(update, options)` | Runs `update` inside `document.startViewTransition` where the browser has one, and plainly where it has not |
729
- | `<Box.Theme viewTransition>` | That call around a theme change, `flushSync` included |
729
+ | `<Box.Theme viewTransition>` | That call around a theme change, `flushSync` included. `viewTransition="reveal"` grows the new theme out of the pressed control as a circle |
730
730
 
731
731
  ```tsx
732
732
  const handle = Box.viewTransition(() => flushSync(() => setTab(next)), { types: ['forward'] });
@@ -756,7 +756,9 @@ interface ViewTransitionHandle {
756
756
  - **In React the update has to be flushed.** The browser takes its second screenshot the moment the
757
757
  callback returns, and a `setState` has not rendered by then — so a hand-rolled version captures the old
758
758
  state twice and nothing appears to move. `flushSync` inside the callback is the fix, and
759
- `<Box.Theme viewTransition>` is it already done for the one change every app has.
759
+ `<Box.Theme viewTransition>` is it already done for the one change every app has. A theme change also
760
+ pauses every CSS transition until the new theme has painted (and the view transition has finished) — `color` is inherited and every Box transitions
761
+ `all`, so each element would start one of its own — which leaves the view transition as the only animation.
760
762
  - **A name has to be unique in the document while the transition runs.** Two elements sharing one is how a
761
763
  transition silently does nothing. The prop is for the handful of names a layout has (`header`, `main`);
762
764
  a name **per list item** is a rule per item that is never freed, so that one goes in
@@ -2365,34 +2367,36 @@ named ones carry the reason.
2365
2367
 
2366
2368
  ### GridDefinition
2367
2369
 
2368
- | Prop | Type | Default | Description |
2369
- | ------------------------- | ------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------- |
2370
- | `columns` | `ColumnType[]` | required | Column definitions |
2371
- | `rowKey` | `keyof TRow \| (row) => Key` | auto | Unique row identifier |
2372
- | `rowHeight` | `number` | `48` | Row height in px |
2373
- | `visibleRowsCount` | `number \| 'all'` | `10` | Visible rows. `'all'` disables virtualization |
2374
- | `showRowNumber` | `boolean \| { pinned?, width? }` | `false` | Row number column |
2375
- | `rowSelection` | `boolean \| { pinned? }` | `false` | Checkbox selection column |
2376
- | `rowDetail` | `RowDetailConfig` | — | Expandable detail panel (see below) |
2377
- | `treeData` | `TreeDataConfig` | — | Rows that hold rows: a `treegrid` with a chevron column (see below) |
2378
- | `groupBy` | `Key[]` | — | The columns the grid starts grouped by, outermost first. The column menu takes it from there |
2379
- | `groupDefaultExpanded` | `boolean \| number` | `false` | Which group rows start open: `true` for all, a number for how many levels down |
2380
- | `editable` | `boolean` | `false` | Whether every column can be edited. A column’s own `editable` takes priority |
2381
- | `onCellEdit` | `(edit) => void \| boolean \| string` | — | Judges an edit and is told about it: nothing accepts, a string refuses. May be async |
2382
- | `dataSource` | `DataSource` | — | The grid fetches its own rows a block at a time; `data` is not read at all |
2383
- | `pagination` | `{ totalCount, pageSize? }` | — | Server-side pagination. Bypasses client-side filtering |
2384
- | `topBar` / `bottomBar` | `boolean` | `false` | Show top/bottom bars |
2385
- | `title` / `topBarContent` | `ReactNode` | — | Top bar content |
2386
- | `globalFilter` | `boolean` | `false` | Enable global fuzzy search |
2387
- | `globalFilterKeys` | `(keyof TRow)[]` | all | Limit global filter columns |
2388
- | `sortable` / `resizable` | `boolean` | `true` | Enable sorting/resizing for all columns |
2389
- | `contextMenu` | `boolean \| ContextMenuConfig` | `true` | Control column header context menu. `false` hides it. Object: `{ sort?, pin?, group? }` |
2390
- | `resizerStyle` | `'visible' \| 'hover' \| 'hidden'` | `'visible'` | Resizer handle visibility. `'hover'`: shows on header cell hover. `'hidden'`: invisible but resize still works |
2391
- | `noDataComponent` | `ReactNode` | `'empty'` | Custom empty state |
2392
- | `footer` | `boolean \| { label? }` | `false` | A pinned row of grand totals over every column with an `aggregate`. `label` replaces the default `Total` |
2393
- | `export` | `boolean \| ExportConfig` | `false` | Export buttons in the top bar: `{ csv?, xlsx?, fileName? }`. The writers load on the first press |
2394
- | `tabNavigation` | `'none' \| 'cells'` | `'none'` | What Tab does. `'none'` is APG's single tab stop; `'cells'` is the spreadsheet reading |
2395
- | `rangeSelection` | `boolean` | `false` | A drag or Shift+arrow marks a block of cells, and `Ctrl+C`/`Ctrl+V` copy and paste it as TSV (see below) |
2370
+ | Prop | Type | Default | Description |
2371
+ | ------------------------- | ------------------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2372
+ | `columns` | `ColumnType[]` | required | Column definitions |
2373
+ | `rowKey` | `keyof TRow \| (row) => Key` | auto | Unique row identifier |
2374
+ | `rowHeight` | `number` | `48` | Row height in px |
2375
+ | `visibleRowsCount` | `number \| 'all'` | `10` | Visible rows. `'all'` disables virtualization |
2376
+ | `showRowNumber` | `boolean \| { pinned?, width? }` | `false` | Row number column |
2377
+ | `rowSelection` | `boolean \| { pinned? }` | `false` | Checkbox selection column. The header checkbox acts on the rows the filters leave on screen; a filter never drops a selection, and the bottom bar counts what it hides, with **Show selected** and **Clear selection** |
2378
+ | `rowDetail` | `RowDetailConfig` | — | Expandable detail panel (see below) |
2379
+ | `treeData` | `TreeDataConfig` | — | Rows that hold rows: a `treegrid` with a chevron column (see below) |
2380
+ | `groupBy` | `Key[]` | — | The columns the grid starts grouped by, outermost first. The column menu takes it from there |
2381
+ | `groupDefaultExpanded` | `boolean \| number` | `false` | Which group rows start open: `true` for all, a number for how many levels down |
2382
+ | `editable` | `boolean` | `false` | Whether every column can be edited. A column’s own `editable` takes priority |
2383
+ | `onCellEdit` | `(edit) => void \| boolean \| string` | — | Judges an edit and is told about it: nothing accepts, a string refuses. May be async |
2384
+ | `dataSource` | `DataSource` | — | The grid fetches its own rows a block at a time; `data` is not read at all |
2385
+ | `pagination` | `{ totalCount, pageSize? }` | — | Server-side pagination. Bypasses client-side filtering |
2386
+ | `topBar` / `bottomBar` | `boolean` | `false` | Show top/bottom bars |
2387
+ | `title` / `topBarContent` | `ReactNode` | — | Top bar content |
2388
+ | `globalFilter` | `boolean` | `false` | Enable global fuzzy search |
2389
+ | `globalFilterKeys` | `(keyof TRow)[]` | all | Limit global filter columns |
2390
+ | `sortable` / `resizable` | `boolean` | `true` | Enable sorting/resizing for all columns |
2391
+ | `contextMenu` | `boolean \| ContextMenuConfig` | `true` | Control column header context menu. `false` hides it. Object: `{ sort?, pin?, group? }` |
2392
+ | `resizerStyle` | `'visible' \| 'hover' \| 'hidden'` | `'visible'` | Resizer handle visibility. `'hover'`: shows on header cell hover. `'hidden'`: invisible but resize still works |
2393
+ | `headerHover` | `'static' \| 'sliding'` | `'static'` | Header hover: an inset pill per sortable cell, or one pill that flows from cell to cell. Whole cell sorts on press |
2394
+ | `localeText` | `Partial<DataGridLocaleText>` | English | Every word the grid writes — labels, accessible names, announcements, messages. Values with a number or a name in them are functions; spread `DATA_GRID_LOCALE_TEXT` to start a translation |
2395
+ | `noDataComponent` | `ReactNode` | `'empty'` | Custom empty state |
2396
+ | `footer` | `boolean \| { label? }` | `false` | A pinned row of grand totals over every column with an `aggregate`. `label` replaces the default `Total` |
2397
+ | `export` | `boolean \| ExportConfig` | `false` | Export buttons in the top bar: `{ csv?, xlsx?, fileName? }`. The writers load on the first press |
2398
+ | `tabNavigation` | `'none' \| 'cells'` | `'none'` | What Tab does. `'none'` is APG's single tab stop; `'cells'` is the spreadsheet reading |
2399
+ | `rangeSelection` | `boolean` | `false` | A drag or Shift+arrow marks a block of cells, and `Ctrl+C`/`Ctrl+V` copy and paste it as TSV (see below) |
2396
2400
 
2397
2401
  ### ColumnType
2398
2402
 
@@ -2404,7 +2408,7 @@ named ones carry the reason.
2404
2408
  | `align` | `'start' \| 'end' \| 'center' \| 'left' \| 'right'` | `'left'` | Cell alignment. `start`/`end` follow the reading order; `left`/`right` stay on the screen side they name |
2405
2409
  | `pin` | `'START' \| 'END'` (also `'LEFT'`/`'RIGHT'`) | — | Pin to an edge of the **inline axis** (sticky on scroll), so it holds under either `dir`. `LEFT`/`RIGHT` are the older spelling of the same two |
2406
2410
  | `columns` | `ColumnType[]` | — | Nested columns (grouped header) |
2407
- | `Cell` | `({ cell }) => ReactNode` | — | Custom renderer. `cell`: `{ value, row, column, grid }` |
2411
+ | `Cell` | `({ cell }) => ReactNode` | — | Custom renderer. `cell`: `{ value, row, column, grid }`. It redraws when its row changes or the grid does — not when another row is selected |
2408
2412
  | `sortable` / `resizable` | `boolean` | inherits | Override grid-level setting |
2409
2413
  | `flexible` | `boolean` | `true` | Participate in flex width distribution |
2410
2414
  | `filterable` | `boolean \| FilterConfig` | — | `true` (text), `{ type: 'number', min?, max? }`, `{ type: 'multiselect', options? }` |
@@ -2787,52 +2791,66 @@ stops, as they were before A7.
2787
2791
 
2788
2792
  ### Component Style Tree
2789
2793
 
2790
- | Component Name | Description | Variants |
2791
- | --------------------------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2792
- | `datagrid` | Root container | — |
2793
- | `datagrid.content` | Scroll container for header + body | — |
2794
- | `datagrid.topBar` | Top bar (title, filters, column groups) | — |
2795
- | `datagrid.topBar.globalFilter` | Global search wrapper | — |
2796
- | `datagrid.topBar.globalFilter.stats` | Filtered rows count badge | — |
2797
- | `datagrid.topBar.columnGroups` | Column group chips container | — |
2798
- | `datagrid.topBar.columnGroups.icon` | Column group icon | — |
2799
- | `datagrid.topBar.columnGroups.separator` | Separator between groups | — |
2800
- | `datagrid.topBar.columnGroups.item` | Column group chip | — |
2801
- | `datagrid.topBar.columnGroups.item.icon` | Remove icon on chip | — |
2802
- | `datagrid.topBar.columnVisibility` | Column visibility dropdown | — |
2803
- | `datagrid.topBar.columnVisibility.badge` | Hidden columns count badge | — |
2804
- | `datagrid.filter.cell` | Filter row cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned` |
2805
- | `datagrid.filter.cell.input` | Filter input container (text/number/multiselect) | — |
2806
- | `datagrid.header` | Header grid container (sticky) | — |
2807
- | `datagrid.header.cell` | Header cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned`, `isSortable`, `isRowSelection`, `isRowNumber`, `isFirstLeaf`, `isLastLeaf`, `isEmptyCell` |
2808
- | `datagrid.header.cell.contextMenu` | Column context menu button | — |
2809
- | `datagrid.header.cell.contextMenu.icon` | Context menu icon | — |
2810
- | `datagrid.header.cell.contextMenu.tooltip` | Context menu popup | — |
2811
- | `datagrid.header.cell.contextMenu.tooltip.item` | Context menu action | — |
2812
- | `datagrid.header.cell.contextMenu.tooltip.item.icon` | Action icon | — |
2813
- | `datagrid.header.cell.contextMenu.tooltip.item.separator` | Menu separator line | — |
2814
- | `datagrid.header.cell.resizer` | Column resize handle | — |
2815
- | `datagrid.body` | Body grid container (virtualized rows) | — |
2816
- | `datagrid.body.cell` | Body cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned`, `isRowNumber`, `isRowSelection`, `isRowSelected`, `isFirstLeaf`, `isLastLeaf`, `isEmptyCell`, `isEditing`, `isInvalid` |
2817
- | `datagrid.body.cell.text` | Default cell text renderer | — |
2818
- | `datagrid.body.cell.editor` | The open cell editor | `isPending` |
2819
- | `datagrid.body.cell.error` | What a refused value says, in the top layer | — |
2820
- | `datagrid.body.cell.rowDetail` | Row detail expand/collapse button | — |
2821
- | `datagrid.body.cell.tree` | Tree cell: the indent, the chevron and the value | — |
2822
- | `datagrid.body.cell.tree.toggle` | Tree expand/collapse chevron | `isExpanded` |
2823
- | `datagrid.body.cell.tree.spacer` | What a leaf puts where its chevron would be | — |
2824
- | `datagrid.body.row` | Data row (display: contents) | — |
2825
- | `datagrid.body.groupRow` | Group row (display: contents) | — |
2826
- | `datagrid.body.groupRow.expandButton` | Group expand/collapse button | — |
2827
- | `datagrid.body.detailRow` | Expanded detail row | — |
2828
- | `datagrid.body.empty` | Empty state container | — |
2829
- | `datagrid.emptyColumns` | No columns selected placeholder | — |
2830
- | `datagrid.bottomBar` | Bottom bar (row count, pagination) | — |
2831
- | `datagrid.bottomBar.info` | Status text ("Rows: ...", "Selected: ...") | — |
2832
- | `datagrid.bottomBar.clearFilters` | "Clear filters" link | — |
2833
- | `datagrid.bottomBar.pagination` | Pagination controls wrapper | — |
2834
- | `datagrid.bottomBar.pagination.button` | Pagination nav button | — |
2835
- | `datagrid.bottomBar.pagination.info` | Page info text ("1 of 5") | — |
2794
+ | Component Name | Description | Variants |
2795
+ | --------------------------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2796
+ | `datagrid` | Root container | — |
2797
+ | `datagrid.content` | Scroll container for header + body | — |
2798
+ | `datagrid.topBar` | Top bar (title, filters, column groups) | — |
2799
+ | `datagrid.topBar.globalFilter` | Global search wrapper | — |
2800
+ | `datagrid.topBar.globalFilter.stats` | Filtered rows count badge (only without a bottom bar) | — |
2801
+ | `datagrid.topBar.columnGroups` | Column group chips container | — |
2802
+ | `datagrid.topBar.columnGroups.icon` | Column group icon | — |
2803
+ | `datagrid.topBar.columnGroups.separator` | Separator between groups | — |
2804
+ | `datagrid.topBar.columnGroups.item` | Column group chip | — |
2805
+ | `datagrid.topBar.columnGroups.item.icon` | Remove icon on chip | — |
2806
+ | `datagrid.topBar.columnVisibility` | Columns button (opens the columns panel) | — |
2807
+ | `datagrid.topBar.columnVisibility.badge` | Shown/total count, only while columns are hidden | `empty` |
2808
+ | `datagrid.topBar.columnVisibility.panel` | Columns panel body | — |
2809
+ | `datagrid.topBar.columnVisibility.search` | Search row (past six columns) | — |
2810
+ | `datagrid.topBar.columnVisibility.searchIcon` | Magnifier inside the search field | — |
2811
+ | `datagrid.topBar.columnVisibility.searchInput` | Search field | — |
2812
+ | `datagrid.topBar.columnVisibility.toolbar` | Count + Show all / Hide all row | — |
2813
+ | `datagrid.topBar.columnVisibility.count` | "6 of 8 shown" | — |
2814
+ | `datagrid.topBar.columnVisibility.action` | Show all / Hide all buttons | — |
2815
+ | `datagrid.topBar.columnVisibility.list` | Scrolling list of switches | — |
2816
+ | `datagrid.topBar.columnVisibility.section` | A run of columns under one header group | `divided` |
2817
+ | `datagrid.topBar.columnVisibility.group` | Header group name above its columns | — |
2818
+ | `datagrid.topBar.columnVisibility.item` | One column: label + switch (the `<label>`) | — |
2819
+ | `datagrid.topBar.columnVisibility.empty` | No-match message | — |
2820
+ | `datagrid.filter.cell` | Filter row cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned` |
2821
+ | `datagrid.filter.cell.input` | Filter input container (text/number/multiselect) | — |
2822
+ | `datagrid.header` | Header grid container (sticky) | — |
2823
+ | `datagrid.header.cell` | Header cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned`, `isSortable`, `isRowSelection`, `isRowNumber`, `isFirstLeaf`, `isLastLeaf`, `isEmptyCell` |
2824
+ | `datagrid.header.cell.contextMenu` | Column context menu button | — |
2825
+ | `datagrid.header.cell.contextMenu.icon` | Context menu icon | — |
2826
+ | `datagrid.header.cell.contextMenu.tooltip` | Context menu popup | — |
2827
+ | `datagrid.header.cell.contextMenu.tooltip.item` | Context menu action | — |
2828
+ | `datagrid.header.cell.contextMenu.tooltip.item.icon` | Action icon | — |
2829
+ | `datagrid.header.cell.contextMenu.tooltip.item.separator` | Menu separator line | — |
2830
+ | `datagrid.header.cell.resizer` | Column resize handle | — |
2831
+ | `datagrid.body` | Body grid container (virtualized rows) | — |
2832
+ | `datagrid.body.cell` | Body cell | `isPinned`, `isFirstLeftPinned`, `isLastLeftPinned`, `isFirstRightPinned`, `isLastRightPinned`, `isRowNumber`, `isRowSelection`, `isRowSelected`, `isFirstLeaf`, `isLastLeaf`, `isEmptyCell`, `isEditing`, `isInvalid` |
2833
+ | `datagrid.body.cell.text` | Default cell text renderer | — |
2834
+ | `datagrid.body.cell.editor` | The open cell editor | `isPending` |
2835
+ | `datagrid.body.cell.error` | What a refused value says, in the top layer | — |
2836
+ | `datagrid.body.cell.rowDetail` | Row detail expand/collapse button | — |
2837
+ | `datagrid.body.cell.tree` | Tree cell: the indent, the chevron and the value | — |
2838
+ | `datagrid.body.cell.tree.toggle` | Tree expand/collapse chevron | `isExpanded` |
2839
+ | `datagrid.body.cell.tree.spacer` | What a leaf puts where its chevron would be | — |
2840
+ | `datagrid.body.row` | Data row (display: contents) | — |
2841
+ | `datagrid.body.groupRow` | Group row (display: contents) | — |
2842
+ | `datagrid.body.groupRow.expandButton` | Group expand/collapse button | — |
2843
+ | `datagrid.body.detailRow` | Expanded detail row | — |
2844
+ | `datagrid.body.empty` | Empty state container | — |
2845
+ | `datagrid.emptyColumns` | No columns selected placeholder | — |
2846
+ | `datagrid.bottomBar` | Bottom bar (row count, pagination) | — |
2847
+ | `datagrid.bottomBar.info` | Status text ("Rows: ...", "Selected: ...") | — |
2848
+ | `datagrid.bottomBar.clearFilters` | "Clear filters" button | — |
2849
+ | `datagrid.bottomBar.selection` | The selection count and its buttons, at the bar's far end | — |
2850
+ | `datagrid.bottomBar.action` | "Show selected" and "Clear selection" | `pressed` (Show selected while it is on) |
2851
+ | `datagrid.bottomBar.pagination` | Pagination controls wrapper | — |
2852
+ | `datagrid.bottomBar.pagination.button` | Pagination nav button | — |
2853
+ | `datagrid.bottomBar.pagination.info` | Page info text ("1 of 5") | — |
2836
2854
 
2837
2855
  ---
2838
2856
 
package/README.md CHANGED
@@ -10,7 +10,7 @@ pass at runtime and caches every rule by its content, so the same value anywhere
10
10
  one class — a project styles itself in TypeScript, with no CSS files to write and no class-name
11
11
  convention to remember.
12
12
 
13
- [Docs and live demos](https://www.box-kite.dev) · [Contributing](CONTRIBUTING.md) ·
13
+ [Docs and live demos](https://www.box-kite.dev) · [Blog](https://www.box-kite.dev/blog/) · [Contributing](CONTRIBUTING.md) ·
14
14
  [Support](SUPPORT.md) · [Security](SECURITY.md) ·
15
15
  [Releases](https://github.com/box-kite/box-kite/releases)
16
16
 
package/client.cjs CHANGED
@@ -1 +1 @@
1
- const e=require("./rolldown-runtime.cjs"),t=require("./react-shared.cjs"),n=require("./platform.cjs"),r=require("./effects.cjs"),i=require("./box.cjs");let a=require("react");a=e.t(a,1);let o=require("@box-kite/core"),s=require("react-dom"),c=require("react/jsx-runtime");function l(e){let{node:t=null,event:r=`click`,hideOnScroll:i=!1,hideOnResize:o=!1,hideOnEscape:s=!0}=e??{},[c,l]=(0,a.useState)(!1),u=(0,a.useRef)(null);return(0,a.useEffect)(()=>{function e(e){let r=t??u.current;r&&!n.l(e,[r])&&l(!1)}function a(){l(!1)}function d(e){e.key===`Escape`&&l(!1)}let f=new AbortController;return c&&(window.addEventListener(r,e,f),s&&window.addEventListener(`keydown`,d,f),o&&window.addEventListener(`resize`,a,f),i&&window.addEventListener(`scroll`,e,{signal:f.signal,capture:!0})),()=>{f.abort()}},[t,c,r,s,o,i]),[c,l,u]}var u=r.t;function d(e,n){let{classNames:r,signature:i,styleElements:a}=t.l(e,n);return u(()=>{(0,o.getDefaultEngine)().flushSync()},[i??e]),{classNames:r,styleElements:a}}function f(e,n){let r=e?(0,o.getDefaultEngine)().addGlobalStyles(e,n):void 0;return u(()=>{(0,o.getDefaultEngine)().flushSync()},[e,n]),t.u(r)}var p;(function(e){function t(){(0,o.getDefaultEngine)().flushSync()}e.flushSync=t;function n(){(0,o.getDefaultEngine)().clear()}e.clear=n;function r(){return(0,o.getDefaultEngine)().getStyles()}e.getStyles=r;function i(){return(0,o.getDefaultEngine)().getStyleTag()}e.getStyleTag=i;function a(){return(0,o.getDefaultEngine)().styleElementId}e.styleElementId=a;function s(e){(0,o.getDefaultEngine)().configure(e)}e.configure=s})(p||={});var m=`[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19`;function h(e){if(typeof e.createContext!=`function`)throw Error(m)}h(a.default);var g=a.default.createContext({theme:``,setTheme:()=>{}});function _(e){let{children:t,theme:n,use:r=`local`,storageKey:l,globalStyles:u,viewTransition:d}=e,p=f(r===`global`?u:void 0,`html`),[m,h]=(0,a.useState)(n??o.defaultThemeName),[_,v]=(0,a.useState)(n!==void 0),y=(0,a.useRef)(null),b=(0,a.useRef)(m),x=(0,a.useCallback)(e=>{let t=()=>{e===null?(l&&(0,o.clearStoredTheme)(l),v(!1)):(l&&(0,o.writeStoredTheme)(l,e),h(e),v(!0))};d?(0,o.startViewTransition)(()=>(0,s.flushSync)(t)):t()},[l,d]),[S,C]=(0,a.useState)(n);return n!==S&&(C(n),n===void 0?v(!1):(h(n),v(!0))),(0,a.useLayoutEffect)(()=>{if(_)return;let e=l?(0,o.readStoredTheme)(l):null,t=e??(0,o.getSystemTheme)();if(t!==b.current&&(y.current=t),h(t),e){v(!0);return}return(0,o.watchSystemTheme)(h)},[_,l]),(0,a.useLayoutEffect)(()=>{if(b.current=m,y.current!==null&&y.current!==m||(y.current=null,r===`local`))return;let e=(0,o.documentRoot)();if(e)return(0,o.applyThemeToElement)(e,m)},[m,r]),r===`local`?(0,c.jsxs)(g.Provider,{value:{theme:m,setTheme:x},children:[p,(0,c.jsx)(i.default,{className:m,props:{"data-theme":m},children:t})]}):(0,c.jsxs)(g.Provider,{value:{theme:m,setTheme:x},children:[p,t]})}(function(e){function t(){let{theme:e,setTheme:t}=(0,a.useContext)(g);return[e,t]}e.useTheme=t})(_||={});var v=_,y=new WeakMap;function b(e){let t=y.get(e);return t||(t=new Map,y.set(e,t)),t}function x(e=!0){let[t]=v.useTheme(),r=(0,a.useMemo)(()=>{if(!e)return null;let t=n.t();if(!t)return null;let r=`box-kite-portal`,i=t.getElementById(r);return i||(i=document.createElement(`div`),i.id=r,document.body.appendChild(i)),i},[e]);return(0,a.useLayoutEffect)(()=>{if(!t||!r)return;let e=b(r),n=e.get(t)??0;return e.set(t,n+1),n===0&&r.classList.add(t),()=>{let n=(e.get(t)??1)-1;n<=0?(e.delete(t),r.classList.remove(t)):e.set(t,n)}},[r,t]),r}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return x}});
1
+ const e=require("./rolldown-runtime.cjs"),t=require("./react-shared.cjs"),n=require("./platform.cjs"),r=require("./effects.cjs"),i=require("./box.cjs");let a=require("react");a=e.t(a,1);let o=require("@box-kite/core"),s=require("react-dom"),c=require("react/jsx-runtime");function l(e){let{node:t=null,event:r=`click`,hideOnScroll:i=!1,hideOnResize:o=!1,hideOnEscape:s=!0}=e??{},[c,l]=(0,a.useState)(!1),u=(0,a.useRef)(null);return(0,a.useEffect)(()=>{function e(e){let r=t??u.current;r&&!n.l(e,[r])&&l(!1)}function a(){l(!1)}function d(e){e.key===`Escape`&&l(!1)}let f=new AbortController;return c&&(window.addEventListener(r,e,f),s&&window.addEventListener(`keydown`,d,f),o&&window.addEventListener(`resize`,a,f),i&&window.addEventListener(`scroll`,e,{signal:f.signal,capture:!0})),()=>{f.abort()}},[t,c,r,s,o,i]),[c,l,u]}var u=r.t;function d(e,n){let{classNames:r,signature:i,styleElements:a}=t.l(e,n);return u(()=>{(0,o.getDefaultEngine)().flushSync()},[i??e]),{classNames:r,styleElements:a}}function f(e,n){let r=e?(0,o.getDefaultEngine)().addGlobalStyles(e,n):void 0;return u(()=>{(0,o.getDefaultEngine)().flushSync()},[e,n]),t.u(r)}var p;(function(e){function t(){(0,o.getDefaultEngine)().flushSync()}e.flushSync=t;function n(){(0,o.getDefaultEngine)().clear()}e.clear=n;function r(){return(0,o.getDefaultEngine)().getStyles()}e.getStyles=r;function i(){return(0,o.getDefaultEngine)().getStyleTag()}e.getStyleTag=i;function a(){return(0,o.getDefaultEngine)().styleElementId}e.styleElementId=a;function s(e){(0,o.getDefaultEngine)().configure(e)}e.configure=s})(p||={});var m=`[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19`;function h(e){if(typeof e.createContext!=`function`)throw Error(m)}h(a.default);var g=a.default.createContext({theme:``,setTheme:()=>{}});function _(e){let{children:t,theme:n,use:l=`local`,storageKey:u,globalStyles:d,viewTransition:p}=e,m=f(l===`global`?d:void 0,`html`),[h,_]=(0,a.useState)(n??o.defaultThemeName),[v,y]=(0,a.useState)(n!==void 0),b=(0,a.useRef)(null),x=(0,a.useRef)(h),S=(0,a.useRef)(null),C=(0,a.useRef)(void 0),w=(0,a.useCallback)(e=>{let t=()=>{e===null?(u&&(0,o.clearStoredTheme)(u),y(!1)):(u&&(0,o.writeStoredTheme)(u,e),_(e),y(!0))};if(p){let e=(0,o.transitionTheme)(()=>(0,s.flushSync)(t),p===`reveal`?`reveal`:`fade`);C.current=e.finished,e.finished.then(()=>C.current=void 0,()=>C.current=void 0)}else t()},[u,p]),T=p===`reveal`;(0,a.useEffect)(()=>T?(0,o.prepareReveal)():void 0,[T]);let[E,D]=(0,a.useState)(n);return n!==E&&(D(n),n===void 0?y(!1):(_(n),y(!0))),(0,a.useLayoutEffect)(()=>{if(v)return;let e=u?(0,o.readStoredTheme)(u):null,t=e??(0,o.getSystemTheme)();if(t!==x.current&&(b.current=t),_(t),e){y(!0);return}return(0,o.watchSystemTheme)(_)},[v,u]),r.t(()=>{h!==x.current&&(S.current??=(0,o.pauseTransitions)())},[h]),(0,a.useLayoutEffect)(()=>{if(x.current=h,b.current!==null&&b.current!==h)return;b.current=null;let e=S.current;S.current=null;let t=l===`global`?(0,o.documentRoot)():null,n=t?(0,o.applyThemeToElement)(t,h):void 0;return e?.(C.current),n},[h,l]),l===`local`?(0,c.jsxs)(g.Provider,{value:{theme:h,setTheme:w},children:[m,(0,c.jsx)(i.default,{className:h,props:{"data-theme":h},children:t})]}):(0,c.jsxs)(g.Provider,{value:{theme:h,setTheme:w},children:[m,t]})}(function(e){function t(){let{theme:e,setTheme:t}=(0,a.useContext)(g);return[e,t]}e.useTheme=t})(_||={});var v=_,y=new WeakMap;function b(e){let t=y.get(e);return t||(t=new Map,y.set(e,t)),t}function x(e=!0){let[t]=v.useTheme(),r=(0,a.useMemo)(()=>{if(!e)return null;let t=n.t();if(!t)return null;let r=`box-kite-portal`,i=t.getElementById(r);return i||(i=document.createElement(`div`),i.id=r,document.body.appendChild(i)),i},[e]);return(0,a.useLayoutEffect)(()=>{if(!t||!r)return;let e=b(r),n=e.get(t)??0;return e.set(t,n+1),n===0&&r.classList.add(t),()=>{let n=(e.get(t)??1)-1;n<=0?(e.delete(t),r.classList.remove(t)):e.set(t,n)}},[r,t]),r}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return x}});
package/client.mjs CHANGED
@@ -3,11 +3,11 @@ import { l as n, t as r } from "./platform.mjs";
3
3
  import { t as i } from "./effects.mjs";
4
4
  import a from "./box.mjs";
5
5
  import o, { useCallback as s, useContext as c, useEffect as l, useLayoutEffect as u, useMemo as d, useRef as f, useState as p } from "react";
6
- import { applyThemeToElement as m, clearStoredTheme as h, defaultThemeName as g, documentRoot as _, getDefaultEngine as v, getSystemTheme as y, readStoredTheme as b, startViewTransition as x, watchSystemTheme as S, writeStoredTheme as C } from "@box-kite/core";
7
- import { flushSync as w } from "react-dom";
8
- import { jsx as T, jsxs as E } from "react/jsx-runtime";
6
+ import { applyThemeToElement as m, clearStoredTheme as h, defaultThemeName as g, documentRoot as _, getDefaultEngine as v, getSystemTheme as y, pauseTransitions as b, prepareReveal as x, readStoredTheme as S, transitionTheme as C, watchSystemTheme as w, writeStoredTheme as T } from "@box-kite/core";
7
+ import { flushSync as E } from "react-dom";
8
+ import { jsx as D, jsxs as O } from "react/jsx-runtime";
9
9
  //#region src/react/hooks/useVisibility.ts
10
- function D(e) {
10
+ function k(e) {
11
11
  let { node: t = null, event: r = "click", hideOnScroll: i = !1, hideOnResize: a = !1, hideOnEscape: o = !0 } = e ?? {}, [s, c] = p(!1), u = f(null);
12
12
  return l(() => {
13
13
  function e(e) {
@@ -42,23 +42,23 @@ function D(e) {
42
42
  }
43
43
  //#endregion
44
44
  //#region src/react/useStyles.ts
45
- var O = i;
46
- function k(t, n) {
45
+ var A = i;
46
+ function j(t, n) {
47
47
  let { classNames: r, signature: i, styleElements: a } = e(t, n);
48
- return O(() => {
48
+ return A(() => {
49
49
  v().flushSync();
50
50
  }, [i ?? t]), {
51
51
  classNames: r,
52
52
  styleElements: a
53
53
  };
54
54
  }
55
- function A(e, n) {
55
+ function M(e, n) {
56
56
  let r = e ? v().addGlobalStyles(e, n) : void 0;
57
- return O(() => {
57
+ return A(() => {
58
58
  v().flushSync();
59
59
  }, [e, n]), t(r);
60
60
  }
61
- var j;
61
+ var N;
62
62
  (function(e) {
63
63
  function t() {
64
64
  v().flushSync();
@@ -84,73 +84,83 @@ var j;
84
84
  v().configure(e);
85
85
  }
86
86
  e.configure = o;
87
- })(j ||= {});
87
+ })(N ||= {});
88
88
  //#endregion
89
89
  //#region src/react/clientRuntime.ts
90
- var M = "[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19";
91
- function N(e) {
92
- if (typeof e.createContext != "function") throw Error(M);
90
+ var P = "[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19";
91
+ function F(e) {
92
+ if (typeof e.createContext != "function") throw Error(P);
93
93
  }
94
94
  //#endregion
95
95
  //#region src/react/theme/themeContext.ts
96
- N(o);
97
- var P = o.createContext({
96
+ F(o);
97
+ var I = o.createContext({
98
98
  theme: "",
99
99
  setTheme: () => {}
100
100
  });
101
101
  //#endregion
102
102
  //#region src/react/theme/theme.tsx
103
- function F(e) {
104
- let { children: t, theme: n, use: r = "local", storageKey: i, globalStyles: o, viewTransition: c } = e, l = A(r === "global" ? o : void 0, "html"), [d, v] = p(n ?? g), [D, O] = p(n !== void 0), k = f(null), j = f(d), M = s((e) => {
103
+ function L(e) {
104
+ let { children: t, theme: n, use: r = "local", storageKey: o, globalStyles: c, viewTransition: d } = e, v = M(r === "global" ? c : void 0, "html"), [k, A] = p(n ?? g), [j, N] = p(n !== void 0), P = f(null), F = f(k), L = f(null), R = f(void 0), z = s((e) => {
105
105
  let t = () => {
106
- e === null ? (i && h(i), O(!1)) : (i && C(i, e), v(e), O(!0));
106
+ e === null ? (o && h(o), N(!1)) : (o && T(o, e), A(e), N(!0));
107
107
  };
108
- c ? x(() => w(t)) : t();
109
- }, [i, c]), [N, F] = p(n);
110
- return n !== N && (F(n), n === void 0 ? O(!1) : (v(n), O(!0))), u(() => {
111
- if (D) return;
112
- let e = i ? b(i) : null, t = e ?? y();
113
- if (t !== j.current && (k.current = t), v(t), e) {
114
- O(!0);
108
+ if (d) {
109
+ let e = C(() => E(t), d === "reveal" ? "reveal" : "fade");
110
+ R.current = e.finished, e.finished.then(() => R.current = void 0, () => R.current = void 0);
111
+ } else t();
112
+ }, [o, d]), B = d === "reveal";
113
+ l(() => B ? x() : void 0, [B]);
114
+ let [V, H] = p(n);
115
+ return n !== V && (H(n), n === void 0 ? N(!1) : (A(n), N(!0))), u(() => {
116
+ if (j) return;
117
+ let e = o ? S(o) : null, t = e ?? y();
118
+ if (t !== F.current && (P.current = t), A(t), e) {
119
+ N(!0);
115
120
  return;
116
121
  }
117
- return S(v);
118
- }, [D, i]), u(() => {
119
- if (j.current = d, k.current !== null && k.current !== d || (k.current = null, r === "local")) return;
120
- let e = _();
121
- if (e) return m(e, d);
122
- }, [d, r]), r === "local" ? /* @__PURE__ */ E(P.Provider, {
122
+ return w(A);
123
+ }, [j, o]), i(() => {
124
+ k !== F.current && (L.current ??= b());
125
+ }, [k]), u(() => {
126
+ if (F.current = k, P.current !== null && P.current !== k) return;
127
+ P.current = null;
128
+ let e = L.current;
129
+ L.current = null;
130
+ let t = r === "global" ? _() : null, n = t ? m(t, k) : void 0;
131
+ return e?.(R.current), n;
132
+ }, [k, r]), r === "local" ? /* @__PURE__ */ O(I.Provider, {
123
133
  value: {
124
- theme: d,
125
- setTheme: M
134
+ theme: k,
135
+ setTheme: z
126
136
  },
127
- children: [l, /* @__PURE__ */ T(a, {
128
- className: d,
129
- props: { "data-theme": d },
137
+ children: [v, /* @__PURE__ */ D(a, {
138
+ className: k,
139
+ props: { "data-theme": k },
130
140
  children: t
131
141
  })]
132
- }) : /* @__PURE__ */ E(P.Provider, {
142
+ }) : /* @__PURE__ */ O(I.Provider, {
133
143
  value: {
134
- theme: d,
135
- setTheme: M
144
+ theme: k,
145
+ setTheme: z
136
146
  },
137
- children: [l, t]
147
+ children: [v, t]
138
148
  });
139
149
  }
140
150
  (function(e) {
141
151
  function t() {
142
- let { theme: e, setTheme: t } = c(P);
152
+ let { theme: e, setTheme: t } = c(I);
143
153
  return [e, t];
144
154
  }
145
155
  e.useTheme = t;
146
- })(F ||= {});
147
- var I = F, L = /* @__PURE__ */ new WeakMap();
148
- function R(e) {
149
- let t = L.get(e);
150
- return t || (t = /* @__PURE__ */ new Map(), L.set(e, t)), t;
156
+ })(L ||= {});
157
+ var R = L, z = /* @__PURE__ */ new WeakMap();
158
+ function B(e) {
159
+ let t = z.get(e);
160
+ return t || (t = /* @__PURE__ */ new Map(), z.set(e, t)), t;
151
161
  }
152
- function z(e = !0) {
153
- let [t] = I.useTheme(), n = d(() => {
162
+ function V(e = !0) {
163
+ let [t] = R.useTheme(), n = d(() => {
154
164
  if (!e) return null;
155
165
  let t = r();
156
166
  if (!t) return null;
@@ -159,7 +169,7 @@ function z(e = !0) {
159
169
  }, [e]);
160
170
  return u(() => {
161
171
  if (!t || !n) return;
162
- let e = R(n), r = e.get(t) ?? 0;
172
+ let e = B(n), r = e.get(t) ?? 0;
163
173
  return e.set(t, r + 1), r === 0 && n.classList.add(t), () => {
164
174
  let r = (e.get(t) ?? 1) - 1;
165
175
  r <= 0 ? (e.delete(t), n.classList.remove(t)) : e.set(t, r);
@@ -167,4 +177,4 @@ function z(e = !0) {
167
177
  }, [n, t]), n;
168
178
  }
169
179
  //#endregion
170
- export { D as a, k as i, I as n, j as r, z as t };
180
+ export { k as a, j as i, R as n, N as r, V as t };
@@ -0,0 +1,7 @@
1
+ import { default as GridModel } from '../models/gridModel';
2
+ interface Props<TRow> {
3
+ grid: GridModel<TRow>;
4
+ }
5
+ /** The selection's half of the bottom bar: the count, how much of it the filters hide, and the two ways out. */
6
+ export default function DataGridBottomBarSelection<TRow>(props: Props<TRow>): import("react").JSX.Element;
7
+ export {};
@@ -0,0 +1,10 @@
1
+ import { default as GridModel } from '../models/gridModel';
2
+ interface Props<TRow> {
3
+ grid: GridModel<TRow>;
4
+ }
5
+ /**
6
+ * The columns button and its panel: a non-modal dialog with a search field, the count and the two bulk
7
+ * actions, and one switch per column under its header group's name.
8
+ */
9
+ export default function DataGridColumnsPanel<TRow>(props: Props<TRow>): import("react").JSX.Element;
10
+ export {};
@@ -4,10 +4,10 @@ interface Props<TRow> {
4
4
  /** Position in the whole row list, not in the rendered window. */
5
5
  index: number;
6
6
  /**
7
- * The grid's store version. Not read: it is what tells the memo below that something the row draws
8
- * from the model has moved, since every other prop it takes holds still while the window slides.
7
+ * This row's version (`GridModel.rowVersion`). Not read: it is what tells the memo below that something
8
+ * the row draws from the model has moved, since every other prop it takes holds still while the window slides.
9
9
  */
10
- version: number;
10
+ version: string;
11
11
  }
12
12
  declare function DataGridDetailRowImpl<TRow>(props: Props<TRow>): import("react").JSX.Element;
13
13
  /**
@@ -4,10 +4,10 @@ interface Props<TRow> {
4
4
  /** Position in the whole row list, not in the rendered window. */
5
5
  index: number;
6
6
  /**
7
- * The grid's store version. Not read: it is what tells the memo below that something the row draws
8
- * from the model has moved, since every other prop it takes holds still while the window slides.
7
+ * This row's version (`GridModel.rowVersion`). Not read: it is what tells the memo below that something
8
+ * the row draws from the model has moved, since every other prop it takes holds still while the window slides.
9
9
  */
10
- version: number;
10
+ version: string;
11
11
  }
12
12
  declare function DataGridGroupRowImpl<TRow>(props: Props<TRow>): import("react").JSX.Element;
13
13
  /**
@@ -1,6 +1,10 @@
1
1
  import { default as GridModel } from '../models/gridModel';
2
2
  interface Props<TRow> {
3
3
  grid: GridModel<TRow>;
4
+ /** `GridModel.headerVersion`. Not read: it is what tells the memo below the header has something new to draw. */
5
+ version: string;
4
6
  }
5
- export default function DataGridHeader<TRow>(props: Props<TRow>): import("react").JSX.Element;
6
- export {};
7
+ declare function DataGridHeaderImpl<TRow>(props: Props<TRow>): import("react").JSX.Element;
8
+ /** Memoized, so a press that only moves the tab stop does not redraw the header and the filters under it. */
9
+ declare const DataGridHeader: typeof DataGridHeaderImpl;
10
+ export default DataGridHeader;
@@ -4,10 +4,10 @@ interface Props<TRow> {
4
4
  /** Position in the whole row list, not in the rendered window. */
5
5
  index: number;
6
6
  /**
7
- * The grid's store version. Not read: it is what tells the memo below that something the row draws
8
- * from the model has moved, since every other prop it takes holds still while the window slides.
7
+ * This row's version (`GridModel.rowVersion`). Not read: it is what tells the memo below that something
8
+ * the row draws from the model has moved, since every other prop it takes holds still while the window slides.
9
9
  */
10
- version: number;
10
+ version: string;
11
11
  }
12
12
  declare function DataGridRowImpl<TRow>(props: Props<TRow>): import("react").JSX.Element;
13
13
  /**