@box-kite/react 0.0.1 → 2.0.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 (280) hide show
  1. package/.claude/rules/box-kite-rules.md +65 -0
  2. package/.claude/skills/box-kite/SKILL.md +138 -0
  3. package/.claude/skills/box-kite/references/components.md +235 -0
  4. package/.claude/skills/box-kite/references/extending.md +42 -0
  5. package/.claude/skills/box-kite/references/patterns.md +27 -0
  6. package/.claude/skills/box-kite/references/styling.md +222 -0
  7. package/.cursor/rules/box-kite.mdc +73 -0
  8. package/AGENTS.md +102 -0
  9. package/BOX_AI_CONTEXT.md +2804 -0
  10. package/BOX_KITE_AI_CONTEXT.md +2804 -0
  11. package/LICENSE +21 -0
  12. package/README.md +744 -7
  13. package/a11y.cjs +1 -0
  14. package/a11y.d.ts +15 -0
  15. package/a11y.mjs +4 -0
  16. package/anchor.cjs +1 -0
  17. package/anchor.d.ts +14 -0
  18. package/anchor.mjs +3 -0
  19. package/behavior.cjs +1 -0
  20. package/behavior.mjs +277 -0
  21. package/box.cjs +1 -0
  22. package/box.d.ts +46 -0
  23. package/box.mjs +23 -0
  24. package/client.cjs +1 -0
  25. package/client.mjs +164 -0
  26. package/components/accordion.cjs +1 -0
  27. package/components/accordion.d.ts +114 -0
  28. package/components/accordion.mjs +251 -0
  29. package/components/baseSvg.cjs +1 -0
  30. package/components/baseSvg.d.ts +5 -0
  31. package/components/baseSvg.mjs +21 -0
  32. package/components/button.cjs +1 -0
  33. package/components/button.d.ts +19 -0
  34. package/components/button.mjs +19 -0
  35. package/components/chart.cjs +1 -0
  36. package/components/chart.d.ts +83 -0
  37. package/components/chart.mjs +236 -0
  38. package/components/checkbox.cjs +1 -0
  39. package/components/checkbox.d.ts +36 -0
  40. package/components/checkbox.mjs +38 -0
  41. package/components/combobox/comboboxChips.d.ts +21 -0
  42. package/components/combobox/comboboxListbox.d.ts +47 -0
  43. package/components/combobox.cjs +1 -0
  44. package/components/combobox.d.ts +121 -0
  45. package/components/combobox.mjs +563 -0
  46. package/components/dataGrid/components/dataGridAggregateValue.d.ts +10 -0
  47. package/components/dataGrid/components/dataGridBody.d.ts +7 -0
  48. package/components/dataGrid/components/dataGridBottomBar.d.ts +6 -0
  49. package/components/dataGrid/components/dataGridCell.d.ts +16 -0
  50. package/components/dataGrid/components/dataGridCellEditor.d.ts +15 -0
  51. package/components/dataGrid/components/dataGridCellPlaceholder.d.ts +14 -0
  52. package/components/dataGrid/components/dataGridCellRowDetail.d.ts +6 -0
  53. package/components/dataGrid/components/dataGridCellRowSelection.d.ts +6 -0
  54. package/components/dataGrid/components/dataGridCellText.d.ts +6 -0
  55. package/components/dataGrid/components/dataGridCellTree.d.ts +16 -0
  56. package/components/dataGrid/components/dataGridColumnFilter.d.ts +9 -0
  57. package/components/dataGrid/components/dataGridColumnGroups.d.ts +7 -0
  58. package/components/dataGrid/components/dataGridContent.d.ts +6 -0
  59. package/components/dataGrid/components/dataGridDataSourceError.d.ts +12 -0
  60. package/components/dataGrid/components/dataGridDetailRow.d.ts +8 -0
  61. package/components/dataGrid/components/dataGridEmptyColumns.d.ts +6 -0
  62. package/components/dataGrid/components/dataGridExport.d.ts +10 -0
  63. package/components/dataGrid/components/dataGridFilterCell.d.ts +11 -0
  64. package/components/dataGrid/components/dataGridFilterRow.d.ts +6 -0
  65. package/components/dataGrid/components/dataGridFooter.d.ts +11 -0
  66. package/components/dataGrid/components/dataGridGlobalFilter.d.ts +6 -0
  67. package/components/dataGrid/components/dataGridGroupRow.d.ts +8 -0
  68. package/components/dataGrid/components/dataGridHeader.d.ts +6 -0
  69. package/components/dataGrid/components/dataGridHeaderCell.d.ts +9 -0
  70. package/components/dataGrid/components/dataGridHeaderCellContextMenu.d.ts +11 -0
  71. package/components/dataGrid/components/dataGridHeaderCellResizer.d.ts +14 -0
  72. package/components/dataGrid/components/dataGridLoader.d.ts +11 -0
  73. package/components/dataGrid/components/dataGridPagination.d.ts +6 -0
  74. package/components/dataGrid/components/dataGridRow.d.ts +8 -0
  75. package/components/dataGrid/components/dataGridTopBar.d.ts +6 -0
  76. package/components/dataGrid/components/dataGridTopBarContextMenu.d.ts +6 -0
  77. package/components/dataGrid/contracts/dataGridContract.d.ts +671 -0
  78. package/components/dataGrid/export/gridExport.d.ts +10 -0
  79. package/components/dataGrid/gridNavigationContext.d.ts +32 -0
  80. package/components/dataGrid/models/aggregateCellModel.d.ts +34 -0
  81. package/components/dataGrid/models/aggregationModel.d.ts +32 -0
  82. package/components/dataGrid/models/cellKeys.d.ts +11 -0
  83. package/components/dataGrid/models/cellModel.d.ts +44 -0
  84. package/components/dataGrid/models/columnModel.d.ts +160 -0
  85. package/components/dataGrid/models/columnVisibilityModel.d.ts +24 -0
  86. package/components/dataGrid/models/dataSourceModel.d.ts +177 -0
  87. package/components/dataGrid/models/detailRowModel.d.ts +22 -0
  88. package/components/dataGrid/models/editModel.d.ts +77 -0
  89. package/components/dataGrid/models/exportModel.d.ts +51 -0
  90. package/components/dataGrid/models/filterModel.d.ts +22 -0
  91. package/components/dataGrid/models/gridModel.d.ts +293 -0
  92. package/components/dataGrid/models/groupRowCellModel.d.ts +34 -0
  93. package/components/dataGrid/models/groupRowModel.d.ts +68 -0
  94. package/components/dataGrid/models/headerCellModel.d.ts +83 -0
  95. package/components/dataGrid/models/paginationModel.d.ts +32 -0
  96. package/components/dataGrid/models/rowModel.d.ts +46 -0
  97. package/components/dataGrid/models/sourceGroupRowModel.d.ts +45 -0
  98. package/components/dataGrid/models/sourceLevel.d.ts +71 -0
  99. package/components/dataGrid/models/sourceRowModel.d.ts +29 -0
  100. package/components/dataGrid/models/sourceTreeRowModel.d.ts +23 -0
  101. package/components/dataGrid/models/treeModel.d.ts +94 -0
  102. package/components/dataGrid/models/treeRow.d.ts +22 -0
  103. package/components/dataGrid/models/treeRowModel.d.ts +50 -0
  104. package/components/dataGrid/models/viewportModel.d.ts +44 -0
  105. package/components/dataGrid/useGrid.d.ts +8 -0
  106. package/components/dataGrid/useGridNavigation.d.ts +21 -0
  107. package/components/dataGrid.cjs +1 -0
  108. package/components/dataGrid.d.ts +4 -0
  109. package/components/dataGrid.mjs +4907 -0
  110. package/components/dialog.cjs +1 -0
  111. package/components/dialog.d.ts +151 -0
  112. package/components/dialog.mjs +223 -0
  113. package/components/dropdown/dropdownContext.d.ts +44 -0
  114. package/components/dropdown/dropdownItems.d.ts +22 -0
  115. package/components/dropdown/dropdownRowRenderer.d.ts +8 -0
  116. package/components/dropdown/dropdownSearch.d.ts +21 -0
  117. package/components/dropdown/utils.d.ts +1 -0
  118. package/components/dropdown.cjs +1 -0
  119. package/components/dropdown.d.ts +77 -0
  120. package/components/dropdown.mjs +491 -0
  121. package/components/flex.cjs +1 -0
  122. package/components/flex.d.ts +6 -0
  123. package/components/flex.mjs +16 -0
  124. package/components/form.cjs +1 -0
  125. package/components/form.d.ts +10 -0
  126. package/components/form.mjs +58 -0
  127. package/components/grid.cjs +1 -0
  128. package/components/grid.d.ts +6 -0
  129. package/components/grid.mjs +16 -0
  130. package/components/icon.cjs +1 -0
  131. package/components/icon.d.ts +37 -0
  132. package/components/icon.mjs +41 -0
  133. package/components/menu.cjs +1 -0
  134. package/components/menu.d.ts +234 -0
  135. package/components/menu.mjs +422 -0
  136. package/components/overlay.cjs +1 -0
  137. package/components/overlay.d.ts +47 -0
  138. package/components/overlay.mjs +52 -0
  139. package/components/popover.cjs +1 -0
  140. package/components/popover.d.ts +100 -0
  141. package/components/popover.mjs +69 -0
  142. package/components/presence.cjs +1 -0
  143. package/components/presence.d.ts +36 -0
  144. package/components/presence.mjs +11 -0
  145. package/components/progress.cjs +1 -0
  146. package/components/progress.d.ts +47 -0
  147. package/components/progress.mjs +28 -0
  148. package/components/radioButton.cjs +1 -0
  149. package/components/radioButton.d.ts +32 -0
  150. package/components/radioButton.mjs +32 -0
  151. package/components/radioGroup.cjs +1 -0
  152. package/components/radioGroup.d.ts +51 -0
  153. package/components/radioGroup.mjs +83 -0
  154. package/components/select.cjs +1 -0
  155. package/components/select.d.ts +51 -0
  156. package/components/select.mjs +36 -0
  157. package/components/semantics.cjs +1 -0
  158. package/components/semantics.d.ts +39 -0
  159. package/components/semantics.mjs +17 -0
  160. package/components/slider.cjs +1 -0
  161. package/components/slider.d.ts +98 -0
  162. package/components/slider.mjs +250 -0
  163. package/components/svg.cjs +1 -0
  164. package/components/svg.d.ts +65 -0
  165. package/components/svg.mjs +141 -0
  166. package/components/switch.cjs +1 -0
  167. package/components/switch.d.ts +29 -0
  168. package/components/switch.mjs +25 -0
  169. package/components/tabs.cjs +1 -0
  170. package/components/tabs.d.ts +87 -0
  171. package/components/tabs.mjs +324 -0
  172. package/components/textarea.cjs +1 -0
  173. package/components/textarea.d.ts +41 -0
  174. package/components/textarea.mjs +33 -0
  175. package/components/textbox.cjs +1 -0
  176. package/components/textbox.d.ts +38 -0
  177. package/components/textbox.mjs +33 -0
  178. package/components/toaster.cjs +1 -0
  179. package/components/toaster.d.ts +106 -0
  180. package/components/toaster.mjs +295 -0
  181. package/components/tooltip.cjs +1 -0
  182. package/components/tooltip.d.ts +98 -0
  183. package/components/tooltip.mjs +110 -0
  184. package/components/visuallyHidden.cjs +1 -0
  185. package/components/visuallyHidden.d.ts +6 -0
  186. package/components/visuallyHidden.mjs +23 -0
  187. package/docs/a11y.md +199 -0
  188. package/docs/anchor.md +139 -0
  189. package/docs/components.md +48 -0
  190. package/docs/index.md +11 -0
  191. package/docs/props.md +1777 -0
  192. package/effects.cjs +1 -0
  193. package/effects.mjs +6 -0
  194. package/forms.cjs +1 -0
  195. package/forms.mjs +21 -0
  196. package/gridExport.cjs +2 -0
  197. package/gridExport.mjs +244 -0
  198. package/icons/dotsIcon.d.ts +2 -0
  199. package/icons/expandIcon.d.ts +2 -0
  200. package/icons/groupingIcon.d.ts +2 -0
  201. package/icons/pinIcon.d.ts +2 -0
  202. package/icons/searchIcon.d.ts +2 -0
  203. package/icons/sortIcon.d.ts +2 -0
  204. package/identity.cjs +1 -0
  205. package/identity.mjs +12 -0
  206. package/keyboard.cjs +1 -0
  207. package/keyboard.mjs +30 -0
  208. package/layer.cjs +1 -0
  209. package/layer.mjs +127 -0
  210. package/motion.cjs +1 -0
  211. package/motion.mjs +66 -0
  212. package/package.json +327 -7
  213. package/placement.cjs +1 -0
  214. package/placement.mjs +180 -0
  215. package/platform.cjs +1 -0
  216. package/platform.mjs +45 -0
  217. package/react/a11y/callbacks.d.ts +12 -0
  218. package/react/a11y/useControllableState.d.ts +25 -0
  219. package/react/a11y/useDismiss.d.ts +25 -0
  220. package/react/a11y/useFocusReturn.d.ts +18 -0
  221. package/react/a11y/useRovingFocus.d.ts +84 -0
  222. package/react/anchor/useAnchorPosition.d.ts +79 -0
  223. package/react/animation/usePresence.d.ts +32 -0
  224. package/react/boxClassNames.d.ts +25 -0
  225. package/react/boxProps.d.ts +49 -0
  226. package/react/boxTagProps.d.ts +7 -0
  227. package/react/clientRuntime.d.ts +11 -0
  228. package/react/dialog/useScrollLock.d.ts +12 -0
  229. package/react/effects.d.ts +10 -0
  230. package/react/forms/labelledControl.d.ts +17 -0
  231. package/react/forms/placeholderProp.d.ts +13 -0
  232. package/react/hooks/usePortalContainer.d.ts +6 -0
  233. package/react/hooks/useVirtualization.d.ts +32 -0
  234. package/react/hooks/useVisibility.d.ts +9 -0
  235. package/react/identity/useIdentifier.d.ts +17 -0
  236. package/react/popover/usePopoverLayer.d.ts +87 -0
  237. package/react/reactTypes.d.ts +10 -0
  238. package/react/resolveStyles.d.ts +18 -0
  239. package/react/styleElements.d.ts +3 -0
  240. package/react/svg/attributesInProps.d.ts +4 -0
  241. package/react/svg/svgNaming.d.ts +15 -0
  242. package/react/theme/theme.d.ts +26 -0
  243. package/react/theme/themeContext.d.ts +7 -0
  244. package/react/useStyles.d.ts +22 -0
  245. package/react-shared.cjs +1 -0
  246. package/react-shared.mjs +122 -0
  247. package/rolldown-runtime.cjs +1 -0
  248. package/rsc.cjs +1 -0
  249. package/rsc.d.ts +27 -0
  250. package/rsc.mjs +18 -0
  251. package/ssg.cjs +1 -0
  252. package/ssg.d.ts +24 -0
  253. package/ssg.mjs +25 -0
  254. package/utils/accordion/accordionUtils.d.ts +48 -0
  255. package/utils/anchor/anchorUtils.d.ts +79 -0
  256. package/utils/animation/animationUtils.d.ts +29 -0
  257. package/utils/array/arrayUtils.d.ts +15 -0
  258. package/utils/array/lazyList.d.ts +10 -0
  259. package/utils/box/boxUtils.d.ts +5 -0
  260. package/utils/chart/chartPalette.d.ts +15 -0
  261. package/utils/chart/chartUtils.d.ts +92 -0
  262. package/utils/combobox/comboboxUtils.d.ts +89 -0
  263. package/utils/dom/domUtils.d.ts +32 -0
  264. package/utils/environment/environmentUtils.d.ts +28 -0
  265. package/utils/export/csvUtils.d.ts +23 -0
  266. package/utils/export/downloadUtils.d.ts +12 -0
  267. package/utils/export/xlsxUtils.d.ts +56 -0
  268. package/utils/export/zipUtils.d.ts +26 -0
  269. package/utils/fn/fnUtils.d.ts +4 -0
  270. package/utils/form/formUtils.d.ts +8 -0
  271. package/utils/keyboard/typeaheadUtils.d.ts +31 -0
  272. package/utils/memo.d.ts +10 -0
  273. package/utils/menu/menuUtils.d.ts +25 -0
  274. package/utils/object/objectUtils.d.ts +13 -0
  275. package/utils/slider/sliderUtils.d.ts +67 -0
  276. package/utils/string/fuzzySearch.d.ts +27 -0
  277. package/utils/string/stringUtils.d.ts +4 -0
  278. package/utils/tabs/tabsUtils.d.ts +75 -0
  279. package/utils/toast/toastStore.d.ts +73 -0
  280. package/utils/virtual/virtualUtils.d.ts +47 -0
@@ -0,0 +1,45 @@
1
+ import { AggregateValue, Key } from '../contracts/dataGridContract';
2
+ import { default as ColumnModel } from './columnModel';
3
+ import { default as GridModel } from './gridModel';
4
+ import { default as GroupRowModel } from './groupRowModel';
5
+ import { default as SourceLevel } from './sourceLevel';
6
+ /**
7
+ * One group row of a `def.dataSource` grid: a row of a level the server answered with groups rather than
8
+ * data. It reads its value, its count and its totals *through* the block cache, the way `SourceRowModel`
9
+ * reads a leaf row's — so a block arriving fills in fifty group rows with no model rebuilt.
10
+ *
11
+ * Its children are not here and never were: a group holds a level of its own, fetched when somebody opens
12
+ * it. That is what `count` (the server's number) and `allRows` (empty) are both saying, and it is why the
13
+ * select-all checkbox is not offered — a group cannot select rows the browser has never seen.
14
+ */
15
+ export default class SourceGroupRowModel<TRow> extends GroupRowModel<TRow> {
16
+ private readonly level;
17
+ constructor(grid: GridModel<TRow>, level: SourceLevel<TRow>, groupColumn: ColumnModel<TRow>, rowIndex: number);
18
+ private get row();
19
+ /** The row the server sent for this group: its value, and whatever totals came with it. */
20
+ get data(): TRow | undefined;
21
+ get placeholder(): boolean;
22
+ get groupValue(): Key;
23
+ /** The path that names this group's own level, and the identity the expansion set holds it by. */
24
+ get groupKeys(): Key[];
25
+ /**
26
+ * Keyed by the path rather than by position, so a group stays open while the block under it is dropped
27
+ * and fetched again. A group nobody has yet is keyed by where it sits — `getRowKey` has nothing to read.
28
+ */
29
+ get key(): Key;
30
+ get depth(): number;
31
+ /** The server's count, or nothing at all — a level it could not count cheaply shows the value alone. */
32
+ get count(): number;
33
+ get label(): string;
34
+ /** The totals came down with the group row, because the rows they are over are not in the browser. */
35
+ aggregateValue(column: ColumnModel<TRow>): AggregateValue | undefined;
36
+ get selectable(): boolean;
37
+ get selected(): boolean;
38
+ get indeterminate(): boolean;
39
+ get expanded(): boolean;
40
+ /** Nothing under it is in the browser, so nothing under it can be selected or exported. */
41
+ get allRows(): never[];
42
+ toggleRow(): void;
43
+ }
44
+ /** The key a group path is held by, in `expandedGroupRow` and in this model. */
45
+ export declare function groupPathKey(groupKeys: Key[]): Key;
@@ -0,0 +1,71 @@
1
+ import { Key } from '../contracts/dataGridContract';
2
+ import { default as DataSourceModel } from './dataSourceModel';
3
+ /** Where one block of rows has got to. A block is the unit of a request, of a wait and of a failure. */
4
+ export type BlockStatus = 'loading' | 'loaded' | 'error';
5
+ /**
6
+ * One level of a `def.dataSource` grid: the blocks answering a single path, and the count and end-of-data
7
+ * they arrived with. With nothing opened there is exactly one of these; a group or a tree row being opened
8
+ * adds another, and which of the two the path *is* is the only thing that differs between them.
9
+ *
10
+ * A level knows the row that opened it (`parent`, `parentRowIndex`), because a group's children are worth
11
+ * nothing without it: eviction has to keep the chain above a level in play or the rows on screen would
12
+ * lose the group row they hang off.
13
+ */
14
+ export default class SourceLevel<TRow> {
15
+ private readonly source;
16
+ /** What names this level, outermost first: group values, or a tree row's keys. `[]` is the top. */
17
+ readonly path: Key[];
18
+ readonly parent?: SourceLevel<TRow> | undefined;
19
+ /** Where in `parent` the group row that opened this one sits. A sort can move it. */
20
+ parentRowIndex: number;
21
+ constructor(source: DataSourceModel<TRow>,
22
+ /** What names this level, outermost first: group values, or a tree row's keys. `[]` is the top. */
23
+ path: Key[], parent?: SourceLevel<TRow> | undefined,
24
+ /** Where in `parent` the group row that opened this one sits. A sort can move it. */
25
+ parentRowIndex?: number,
26
+ /** A count carried over an invalidation, so a filter keystroke does not collapse the scrollbar. */
27
+ keepCount?: number);
28
+ private blocks;
29
+ private _totalCount?;
30
+ /** False once disposed of: a request still in flight must not write into a level nobody can reach. */
31
+ private alive;
32
+ /** True once a block came back shorter than it was asked for: there is nothing past it. */
33
+ private _reachedEnd;
34
+ /** Its own identity, and the key it is held under. JSON, so no path value can spell another path. */
35
+ static keyOf(path: Key[]): string;
36
+ get key(): string;
37
+ /** The group this level sits inside — its path, unless the path is a tree's. */
38
+ get groupKeys(): Key[];
39
+ /** The row this level holds the children of — its path, when the path is a tree's. */
40
+ get treeKeys(): Key[];
41
+ /** What a row of this level that has not arrived is keyed by — unique per level, stable per position. */
42
+ get placeholderKey(): string;
43
+ /** How deep this level sits — for a grouped source, which column it groups by. */
44
+ get depth(): number;
45
+ /** Whether its rows are groups rather than data — true until the last grouped column has been named. */
46
+ get isGroupLevel(): boolean;
47
+ /**
48
+ * How many rows this level lays out. The server's count when there is one; otherwise what has been
49
+ * loaded, plus one block to scroll into — which is what keeps an uncounted source reachable.
50
+ */
51
+ get rowCount(): number;
52
+ get totalCount(): number | undefined;
53
+ rowAt(index: number): TRow | undefined;
54
+ /** How many leaf rows a group row holds, when the server said. */
55
+ groupCountAt(index: number): number | undefined;
56
+ statusAt(index: number): BlockStatus | 'missing';
57
+ get isLoading(): boolean;
58
+ failedBlocks(): number[];
59
+ errorAt(index: number): unknown;
60
+ has(index: number): boolean;
61
+ /** Which blocks are in hand, loaded or not — what eviction and the row walks read. */
62
+ loadedBlocks(): {
63
+ index: number;
64
+ rows: TRow[];
65
+ }[];
66
+ drop(index: number): void;
67
+ /** Abort everything in flight and forget the lot — a level whose query or whose group has gone. */
68
+ dispose(): void;
69
+ retry(): void;
70
+ load(index: number): void;
71
+ }
@@ -0,0 +1,29 @@
1
+ import { Key } from '../contracts/dataGridContract';
2
+ import { default as GridModel } from './gridModel';
3
+ import { default as RowModel } from './rowModel';
4
+ import { default as SourceLevel } from './sourceLevel';
5
+ /**
6
+ * One row of a `def.dataSource` grid, whether or not the server has answered for it yet. It reads its
7
+ * values *through* the block cache rather than holding them, which is the whole point: a block arriving
8
+ * changes what fifty rows show with no model rebuilt, and the million rows below the viewport cost one
9
+ * proxy each — that is, nothing, until somebody scrolls to one.
10
+ *
11
+ * Its key follows the same rule. A loaded row is keyed by its data, so a selection or an open detail
12
+ * panel survives the block being dropped and fetched again; a row that is still a skeleton is keyed by
13
+ * its position, since `getRowKey` would mint a fresh id on every render and React would remount it.
14
+ */
15
+ export default class SourceRowModel<TRow> extends RowModel<TRow> {
16
+ /** The level it belongs to: the top one, or the group or tree row somebody opened. */
17
+ protected readonly sourceLevel: SourceLevel<TRow>;
18
+ constructor(grid: GridModel<TRow>,
19
+ /** The level it belongs to: the top one, or the group or tree row somebody opened. */
20
+ sourceLevel: SourceLevel<TRow>, rowIndex: number);
21
+ private get row();
22
+ get data(): TRow;
23
+ get placeholder(): boolean;
24
+ get key(): Key;
25
+ /** Nothing to open and nothing to select: a row nobody has yet is not a row anybody can act on. */
26
+ get expandOnRowClick(): boolean;
27
+ get expanded(): boolean;
28
+ get selected(): boolean;
29
+ }
@@ -0,0 +1,23 @@
1
+ import { default as SourceRowModel } from './sourceRowModel';
2
+ import { TreeRow } from './treeRow';
3
+ /**
4
+ * One row of a lazy tree: a `def.dataSource` row that may hold rows of its own, fetched when somebody
5
+ * opens it. Everything it knows about the tree it reads off its level — how deep it sits, how many
6
+ * siblings it has — so a block landing fills in fifty rows of a tree with no model rebuilt.
7
+ *
8
+ * What is under it is not here and never was, which is the difference from the eager `TreeRowModel`: it
9
+ * cannot walk its own subtree, so a cascading selection is not offered and a row the server has not
10
+ * answered for grows no chevron.
11
+ */
12
+ export default class SourceTreeRowModel<TRow> extends SourceRowModel<TRow> implements TreeRow {
13
+ readonly isTreeRow = true;
14
+ /** How deep the level is, which is how deep every row of it is. */
15
+ get level(): number;
16
+ get position(): number;
17
+ /** The server's count, or `-1` — ARIA's "nobody knows", which is the honest answer to an uncounted level. */
18
+ get siblings(): number;
19
+ /** A row the server has not answered for holds nothing anybody can ask about yet. */
20
+ get hasChildren(): boolean;
21
+ get treeExpanded(): boolean;
22
+ toggleTree: () => void;
23
+ }
@@ -0,0 +1,94 @@
1
+ import { Key, TreeDataConfig } from '../contracts/dataGridContract';
2
+ import { default as GridModel } from './gridModel';
3
+ import { default as TreeRowModel } from './treeRowModel';
4
+ /** One row of the tree and everything under it, before any of it is a model. */
5
+ export interface TreeNode<TRow> {
6
+ data: TRow;
7
+ children: TreeNode<TRow>[];
8
+ }
9
+ /**
10
+ * Rows that hold rows. The shape of the tree comes out of the data — nested in it, or named by a path on
11
+ * every row — and everything else here is what the grid does with it: filtering that keeps a match's
12
+ * ancestors, a sort that happens inside each parent, and which rows are open.
13
+ */
14
+ export default class TreeModel<TRow> {
15
+ readonly grid: GridModel<TRow>;
16
+ constructor(grid: GridModel<TRow>);
17
+ get config(): TreeDataConfig<TRow> | undefined;
18
+ /** Whether the grid is a tree at all — the chevrons, the indent, `role="treegrid"` and the arrow keys. */
19
+ get enabled(): boolean;
20
+ /**
21
+ * Whether the tree is in the browser. The two halves are the same feature from opposite ends: eager
22
+ * reads the shape off `data` and holds the lot, lazy asks the datasource for one level at a time — so
23
+ * everything here that walks the data is the eager half's, and the source owns the other.
24
+ */
25
+ get isEager(): boolean;
26
+ get isLazy(): boolean;
27
+ /**
28
+ * Whether a lazy tree's row holds anything — the one thing a row's own values cannot say, since what
29
+ * is under it has never been in the browser. Eager rows answer it from their node instead.
30
+ */
31
+ rowHasChildren(row: TRow): boolean;
32
+ /** Which column carries the chevrons: the one named, or the first of the caller's own. */
33
+ get columnKey(): Key | undefined;
34
+ /** How far one level indents, on the ÷4 spacing scale. */
35
+ get indent(): number;
36
+ /** Whether ticking a row ticks everything under it. Never on a lazy tree: it cannot reach what it has not got. */
37
+ get cascades(): boolean;
38
+ /** Whether the tree is read off a path per row rather than nested in the rows. */
39
+ private get isFlat();
40
+ private childrenOf;
41
+ private pathOf;
42
+ private buildNested;
43
+ /**
44
+ * The flat shape: every row carries its own path, and the tree is what those paths describe. Shallower
45
+ * rows are taken first (a stable sort, so siblings keep the order they were handed in) — a child cannot
46
+ * find a parent that has not been seen yet, and the data is under no obligation to be in order.
47
+ */
48
+ private buildFlat;
49
+ /**
50
+ * What the filters leave: a row that matches, and every ancestor of one — a match nobody can see the
51
+ * path to is a match the grid has hidden. A parent that matches on its own stays as a leaf, since the
52
+ * rows under it did not.
53
+ */
54
+ private prune;
55
+ /** A sort happens inside each parent: a tree sorted across its levels would not be a tree any more. */
56
+ private sortNodes;
57
+ /**
58
+ * The tree the data describes, filtered and sorted. Its own memo rather than part of `grid.rows`:
59
+ * opening a row rebuilds the models and must not rebuild the tree underneath them.
60
+ */
61
+ readonly nodes: import('../../../utils/memo').Memo<TreeNode<TRow>[]>;
62
+ /**
63
+ * Every row of the tree the filters left, in display order and whatever is open — what a select-all
64
+ * reaches, what the footer totals and what an export writes. `data` is only the top of a nested tree,
65
+ * so nothing that means "every row" can read it.
66
+ */
67
+ readonly allRows: import('../../../utils/memo').Memo<TRow[]>;
68
+ /** Every row in the data, filters ignored: the filter's own options, and what the row count is out of. */
69
+ everyRow(): TRow[];
70
+ /**
71
+ * One model per row that is showing, in display order. A shut row's children are not built at all,
72
+ * which is what keeps a tree nobody has opened the cost of its top level.
73
+ */
74
+ rowList(): TreeRowModel<TRow>[];
75
+ /** Rows opened and rows shut since the grid mounted. Explicit state wins over `defaultExpanded`. */
76
+ private _opened;
77
+ private _closed;
78
+ private _cachedKeys?;
79
+ /** A key list as a set, rebuilt only when the list itself changes — this is read once per row. */
80
+ private keySet;
81
+ private defaultExpanded;
82
+ /**
83
+ * Whether anything could be open at all. A lazy tree's walk reads a key off every row in hand to find
84
+ * the open ones, and a tree nobody has touched is the common case — so it is worth one check first.
85
+ */
86
+ get mayExpand(): boolean;
87
+ isExpanded(key: Key, level: number): boolean;
88
+ /**
89
+ * Every open row, walked down the tree as it is displayed — a row under a shut one is not open however
90
+ * it is marked. Only walked when somebody is listening, since it costs a key for every row it reaches.
91
+ */
92
+ private expandedKeys;
93
+ toggle: (key: Key, level: number) => void;
94
+ }
@@ -0,0 +1,22 @@
1
+ import { default as RowModel } from './rowModel';
2
+ /**
3
+ * What the grid needs of a row that holds rows. Two models answer it and neither can extend the other:
4
+ * the eager `TreeRowModel` holds its node, and the lazy `SourceTreeRowModel` reads its level out of the
5
+ * block cache — so the chevron, the indent and the sideways keys work off this rather than off a class.
6
+ */
7
+ export interface TreeRow {
8
+ /** Duck tag, so the guard below needs neither class in scope and no import cycle with them. */
9
+ readonly isTreeRow: true;
10
+ /** 0 at the top of the tree. `aria-level` is this plus one. */
11
+ readonly level: number;
12
+ /** Where it sits among its siblings, and how many of them there are — `aria-posinset`/`aria-setsize`. */
13
+ readonly position: number;
14
+ readonly siblings: number;
15
+ /** Whether there is anything under it: a row with nothing under it never grows a chevron. */
16
+ readonly hasChildren: boolean;
17
+ /** Whether the rows under it are showing. */
18
+ readonly treeExpanded: boolean;
19
+ readonly toggleTree: () => void;
20
+ }
21
+ /** Whether a row of the grid is one of the tree's. Narrows to a row, since every tree row is one. */
22
+ export declare function isTreeRow<TRow>(row: unknown): row is RowModel<TRow> & TreeRow;
@@ -0,0 +1,50 @@
1
+ import { Key } from '../contracts/dataGridContract';
2
+ import { default as DetailRowModel } from './detailRowModel';
3
+ import { default as GridModel } from './gridModel';
4
+ import { default as RowModel } from './rowModel';
5
+ import { TreeNode } from './treeModel';
6
+ import { TreeRow } from './treeRow';
7
+ /**
8
+ * One row of a `def.treeData` tree: a row of the grid in every sense — its own values, its own cells,
9
+ * its own detail panel — that happens to hold rows of its own. The rows under it are its siblings in the
10
+ * same rowgroup rather than its children in the DOM, which is what `aria-level` is for.
11
+ */
12
+ export default class TreeRowModel<TRow> extends RowModel<TRow> implements TreeRow {
13
+ private readonly node;
14
+ /** 0 at the top of the tree. `aria-level` is this plus one. */
15
+ readonly level: number;
16
+ /** Where it sits among its siblings, and how many of them there are — `aria-posinset`/`aria-setsize`. */
17
+ readonly position: number;
18
+ readonly siblings: number;
19
+ readonly treeParent?: TreeRowModel<TRow> | undefined;
20
+ readonly isTreeRow = true;
21
+ constructor(grid: GridModel<TRow>, node: TreeNode<TRow>, rowIndex: number,
22
+ /** 0 at the top of the tree. `aria-level` is this plus one. */
23
+ level: number,
24
+ /** Where it sits among its siblings, and how many of them there are — `aria-posinset`/`aria-setsize`. */
25
+ position: number, siblings: number, treeParent?: TreeRowModel<TRow> | undefined);
26
+ /** Built by `TreeModel` right after this row, and only where it is open: a shut row renders nothing. */
27
+ children: TreeRowModel<TRow>[];
28
+ /** Whether there is anything under it at all — read off the data, so a shut row still knows. */
29
+ get hasChildren(): boolean;
30
+ /** Whether the rows under it are showing. A row with nothing under it is never open. */
31
+ get treeExpanded(): boolean;
32
+ toggleTree: () => void;
33
+ /**
34
+ * Every key in this row's subtree, its own first. Walked over the *data* rather than the models, so a
35
+ * shut row can still select what is under it; cached per model, and the models are rebuilt whenever
36
+ * the tree is.
37
+ */
38
+ private readonly _subtreeKeys;
39
+ get subtreeKeys(): Key[];
40
+ /**
41
+ * With `selection: 'cascade'` a row is selected when everything under it is — a parent whose children
42
+ * are not all ticked is not itself ticked, which is what makes the indeterminate state mean something.
43
+ */
44
+ get selected(): boolean;
45
+ /** Some of the subtree is selected and some is not. Always false without the cascade. */
46
+ get indeterminate(): boolean;
47
+ toggleSelection: () => void;
48
+ /** This row, its detail panel if one is open, and then everything under it — in display order. */
49
+ get flatRows(): (RowModel<TRow> | DetailRowModel<TRow>)[];
50
+ }
@@ -0,0 +1,44 @@
1
+ import { default as GridModel } from './gridModel';
2
+ /** Windowing parameters for the virtualized body. Rows are sliced by the adapter from these. */
3
+ export interface ViewportWindow {
4
+ /** Index of the first row to render. */
5
+ startIndex: number;
6
+ /** Number of rows to render starting at `startIndex`. */
7
+ take: number;
8
+ /** Pixel offset to translate the rendered slice down to its scroll position. */
9
+ translateY: number;
10
+ /** Total scrollable height of all rows. */
11
+ totalHeight: number;
12
+ /** Fixed viewport height, or undefined when rendering all rows. */
13
+ viewHeight: number | undefined;
14
+ }
15
+ /**
16
+ * Headless virtualization: given a scrollTop, computes which rows are visible and how
17
+ * to position them. Pure math — `scrollTop` is owned by the adapter (so scrolling does
18
+ * not notify the store / re-render the whole grid).
19
+ */
20
+ export default class ViewportModel<TRow> {
21
+ readonly grid: GridModel<TRow>;
22
+ static readonly DEFAULT_VISIBLE_ROWS_COUNT = 10;
23
+ static readonly ROWS_TO_PRELOAD = 20;
24
+ constructor(grid: GridModel<TRow>);
25
+ get showAll(): boolean;
26
+ get hasDetailRows(): boolean;
27
+ get isEmpty(): boolean;
28
+ /** Number of rows the viewport shows at once (all rows when `visibleRowsCount === 'all'`). */
29
+ get visibleRowsCount(): number;
30
+ /**
31
+ * Rows a PageUp/PageDown moves. Deliberately not `visibleRowsCount`, which is every row when
32
+ * `visibleRowsCount === 'all'` — a Page key that jumps to the end of the grid is the End key.
33
+ */
34
+ get pageRows(): number;
35
+ get viewHeight(): number | undefined;
36
+ get totalHeight(): number;
37
+ /** Height to reserve for the empty/no-data state. */
38
+ get emptyHeight(): number;
39
+ /** Where a row sits inside the scrolled body — what a keyboard jump scrolls to. */
40
+ rowTop(index: number): number;
41
+ /** Binary search for the first row whose offset is <= scrollTop (variable-height rows). */
42
+ private findStartIndex;
43
+ window(scrollTop: number): ViewportWindow;
44
+ }
@@ -0,0 +1,8 @@
1
+ import { DataGridProps } from './contracts/dataGridContract';
2
+ import { default as GridModel } from './models/gridModel';
3
+ /**
4
+ * React binding for the headless GridModel store: the model owns all state and behaviour, React only
5
+ * subscribes. `setProps` syncs incoming props during render, and `useSyncExternalStore` re-renders
6
+ * whenever the model notifies.
7
+ */
8
+ export default function useGrid<TRow>(props: DataGridProps<TRow>): GridModel<TRow>;
@@ -0,0 +1,21 @@
1
+ import { GridNavigation } from './gridNavigationContext';
2
+ import { default as GridModel } from './models/gridModel';
3
+ export interface GridNavigationOptions<TRow> {
4
+ grid: GridModel<TRow>;
5
+ /** The scrolling element — a jump to a row outside the rendered window has to scroll first. */
6
+ scrollerRef: React.RefObject<HTMLElement | null>;
7
+ scrollTop: number;
8
+ onScrollTo: (top: number) => void;
9
+ }
10
+ export interface GridNavigator extends GridNavigation {
11
+ /** Put this on the `role="grid"` element: cell keystrokes bubble to it. */
12
+ onKeyDown: (event: React.KeyboardEvent) => void;
13
+ }
14
+ /**
15
+ * APG's grid pattern over a virtualized body. Focus lives on the cells, one in the tab order at a time,
16
+ * and `useRovingFocus` owns which; what belongs here is what virtualization adds — a jump to a row nobody
17
+ * has scrolled to has no element to focus, so the move scrolls, waits for the render it caused, and
18
+ * focuses from a layout effect. Inside a cell the grid steps back: the widget keeps every key, and Enter
19
+ * or F2 got focus there while Escape takes it out.
20
+ */
21
+ export default function useGridNavigation<TRow>(options: GridNavigationOptions<TRow>): GridNavigator;