basalt-ui 1.40.3 → 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 (923) hide show
  1. package/AGENTS.md +50 -45
  2. package/CHANGELOG.md +543 -513
  3. package/MIGRATING.md +969 -37
  4. package/README.md +172 -367
  5. package/agent/rules/basalt-batteries.md +19 -74
  6. package/agent/rules/basalt-charts.md +21 -95
  7. package/agent/rules/basalt-controls.md +23 -131
  8. package/agent/rules/basalt-mantine.md +26 -99
  9. package/agent/rules/basalt-state.md +21 -103
  10. package/agent/rules/basalt-tokens.md +33 -114
  11. package/agent/skills/basalt-app/SKILL.md +229 -72
  12. package/agent/skills/basalt-charts/SKILL.md +23 -57
  13. package/agent/skills/basalt-design/SKILL.md +12 -70
  14. package/agent/templates/AGENTS-block.md.tpl +30 -0
  15. package/agent/templates/DESIGN.md.tpl +2 -2
  16. package/agent/templates/__root.tpl +9 -16
  17. package/agent/templates/main.tpl +21 -0
  18. package/agent/templates/nav.tpl +18 -0
  19. package/configs/check.yml +1 -1
  20. package/configs/oxlint-basalt.json +4 -10
  21. package/configs/oxlint-plugin.js +468 -847
  22. package/configs/oxlint-plugin.test.ts +662 -710
  23. package/configs/oxlint.json +10 -2
  24. package/dist/agent/ai-sdk-transport.d.ts +19 -7
  25. package/dist/agent/ai-sdk-transport.d.ts.map +1 -1
  26. package/dist/agent/ai-sdk-transport.js +10 -7
  27. package/dist/{agent-chat → agent/chat}/composer.d.ts +16 -16
  28. package/dist/agent/chat/composer.d.ts.map +1 -0
  29. package/dist/{agent-chat → agent/chat}/composer.js +10 -9
  30. package/dist/{agent-chat → agent/chat}/message-affordances.d.ts +7 -6
  31. package/dist/agent/chat/message-affordances.d.ts.map +1 -0
  32. package/dist/agent/chat/relative-time.d.ts.map +1 -0
  33. package/dist/{agent-chat → agent/chat}/thread-feed-row.d.ts +18 -16
  34. package/dist/agent/chat/thread-feed-row.d.ts.map +1 -0
  35. package/dist/{agent-chat → agent/chat}/thread-feed-row.js +12 -11
  36. package/dist/{agent-chat → agent/chat}/thread-feed.d.ts +8 -8
  37. package/dist/agent/chat/thread-feed.d.ts.map +1 -0
  38. package/dist/{agent-chat → agent/chat}/thread-feed.js +12 -10
  39. package/dist/{agent-chat → agent/chat}/thread-message.d.ts +12 -9
  40. package/dist/agent/chat/thread-message.d.ts.map +1 -0
  41. package/dist/{agent-chat → agent/chat}/thread-message.js +15 -13
  42. package/dist/{agent-chat → agent/chat}/thread-outcome-card.d.ts +2 -2
  43. package/dist/agent/chat/thread-outcome-card.d.ts.map +1 -0
  44. package/dist/{agent-chat → agent/chat}/thread-outcome-card.js +3 -3
  45. package/dist/{agent-chat → agent/chat}/tool-chip.d.ts +5 -5
  46. package/dist/agent/chat/tool-chip.d.ts.map +1 -0
  47. package/dist/{agent-chat → agent/chat}/tool-chip.js +4 -4
  48. package/dist/agent/chat/use-keyboard-inset.d.ts.map +1 -0
  49. package/dist/{agent-chat → agent/chat}/use-keyboard-inset.js +1 -1
  50. package/dist/{agent-chat → agent/chat}/virtualize.d.ts +7 -7
  51. package/dist/agent/chat/virtualize.d.ts.map +1 -0
  52. package/dist/agent/error.d.ts +31 -0
  53. package/dist/agent/error.d.ts.map +1 -0
  54. package/dist/agent/error.js +18 -0
  55. package/dist/agent/foreign.d.ts +3 -2
  56. package/dist/agent/foreign.d.ts.map +1 -1
  57. package/dist/agent/history.d.ts +2 -36
  58. package/dist/agent/history.d.ts.map +1 -1
  59. package/dist/agent/history.js +0 -32
  60. package/dist/agent/id.d.ts +4 -5
  61. package/dist/agent/id.d.ts.map +1 -1
  62. package/dist/agent/index.d.ts +19 -52
  63. package/dist/agent/index.d.ts.map +1 -1
  64. package/dist/agent/index.js +10 -32
  65. package/dist/agent/outcome.d.ts +3 -14
  66. package/dist/agent/outcome.d.ts.map +1 -1
  67. package/dist/agent/outcome.js +0 -30
  68. package/dist/agent/part-list.d.ts +3 -3
  69. package/dist/agent/part-list.d.ts.map +1 -1
  70. package/dist/agent/parts.d.ts +23 -24
  71. package/dist/agent/parts.d.ts.map +1 -1
  72. package/dist/agent/run-committer.d.ts +23 -0
  73. package/dist/agent/run-committer.d.ts.map +1 -0
  74. package/dist/agent/run-committer.js +41 -0
  75. package/dist/agent/run-records.d.ts +77 -0
  76. package/dist/agent/run-records.d.ts.map +1 -0
  77. package/dist/agent/run-records.js +69 -0
  78. package/dist/agent/thread.d.ts +23 -47
  79. package/dist/agent/thread.d.ts.map +1 -1
  80. package/dist/agent/thread.js +3 -134
  81. package/dist/agent/transport.d.ts +6 -69
  82. package/dist/agent/transport.d.ts.map +1 -1
  83. package/dist/agent/transport.js +0 -18
  84. package/dist/agent/use-agent-thread-runs.d.ts +63 -26
  85. package/dist/agent/use-agent-thread-runs.d.ts.map +1 -1
  86. package/dist/agent/use-agent-thread-runs.js +202 -66
  87. package/dist/charts/BandStrip.d.ts +46 -0
  88. package/dist/charts/BandStrip.d.ts.map +1 -0
  89. package/dist/charts/BandStrip.js +151 -0
  90. package/dist/charts/Bars.d.ts +19 -0
  91. package/dist/charts/Bars.d.ts.map +1 -0
  92. package/dist/charts/Bars.js +77 -0
  93. package/dist/charts/CartesianChart.d.ts +57 -0
  94. package/dist/charts/CartesianChart.d.ts.map +1 -0
  95. package/dist/charts/CartesianChart.js +121 -0
  96. package/dist/charts/ChartCard.d.ts +34 -0
  97. package/dist/charts/ChartCard.d.ts.map +1 -0
  98. package/dist/charts/ChartCard.js +115 -0
  99. package/dist/charts/Donut.d.ts +25 -0
  100. package/dist/charts/Donut.d.ts.map +1 -0
  101. package/dist/charts/Donut.js +191 -0
  102. package/dist/charts/DualPanel.d.ts +47 -0
  103. package/dist/charts/DualPanel.d.ts.map +1 -0
  104. package/dist/charts/DualPanel.js +214 -0
  105. package/dist/charts/Heatmap.d.ts +41 -0
  106. package/dist/charts/Heatmap.d.ts.map +1 -0
  107. package/dist/charts/Heatmap.js +216 -0
  108. package/dist/charts/Lines.d.ts +11 -0
  109. package/dist/charts/Lines.d.ts.map +1 -0
  110. package/dist/charts/Lines.js +114 -0
  111. package/dist/charts/MirroredBars.d.ts +44 -0
  112. package/dist/charts/MirroredBars.d.ts.map +1 -0
  113. package/dist/charts/MirroredBars.js +190 -0
  114. package/dist/charts/Sparkline.d.ts +22 -0
  115. package/dist/charts/Sparkline.d.ts.map +1 -0
  116. package/dist/charts/Sparkline.js +129 -0
  117. package/dist/charts/StackedArea.d.ts +15 -0
  118. package/dist/charts/StackedArea.d.ts.map +1 -0
  119. package/dist/charts/StackedArea.js +46 -0
  120. package/dist/charts/box.d.ts +38 -0
  121. package/dist/charts/box.d.ts.map +1 -0
  122. package/dist/charts/box.js +72 -0
  123. package/dist/charts/card-context.d.ts +3 -0
  124. package/dist/charts/card-context.d.ts.map +1 -0
  125. package/dist/charts/card-context.js +7 -0
  126. package/dist/charts/chart-box.module.css +64 -0
  127. package/{src/content/article-card.module.css.d.ts → dist/charts/chart-box.module.css.d.ts} +5 -9
  128. package/dist/charts/chart-card.module.css +25 -0
  129. package/dist/{dashboard/widget-grid.module.css.d.ts → charts/chart-card.module.css.d.ts} +1 -3
  130. package/dist/charts/chart-legend.module.css +38 -0
  131. package/{src/dashboard/widget-grid.module.css.d.ts → dist/charts/chart-legend.module.css.d.ts} +3 -3
  132. package/dist/charts/compile.d.ts +62 -0
  133. package/dist/charts/compile.d.ts.map +1 -0
  134. package/dist/charts/compile.js +386 -0
  135. package/dist/charts/cursor.d.ts +50 -0
  136. package/dist/charts/cursor.d.ts.map +1 -0
  137. package/dist/charts/cursor.js +157 -0
  138. package/dist/charts/curves.d.ts +12 -0
  139. package/dist/charts/curves.d.ts.map +1 -0
  140. package/dist/charts/curves.js +86 -0
  141. package/dist/charts/donut.module.css +54 -0
  142. package/dist/{content/article-card.module.css.d.ts → charts/donut.module.css.d.ts} +2 -9
  143. package/dist/charts/host.d.ts +17 -0
  144. package/dist/charts/host.d.ts.map +1 -0
  145. package/dist/charts/host.js +35 -0
  146. package/dist/charts/index.d.ts +18 -53
  147. package/dist/charts/index.d.ts.map +1 -1
  148. package/dist/charts/index.js +17 -189
  149. package/dist/charts/legend.d.ts +23 -0
  150. package/dist/charts/legend.d.ts.map +1 -0
  151. package/dist/charts/legend.js +160 -0
  152. package/dist/charts/marks.d.ts +25 -0
  153. package/dist/charts/marks.d.ts.map +1 -0
  154. package/dist/charts/marks.js +128 -0
  155. package/dist/charts/panel.d.ts +56 -0
  156. package/dist/charts/panel.d.ts.map +1 -0
  157. package/dist/charts/panel.js +123 -0
  158. package/dist/charts/scales.d.ts +44 -0
  159. package/dist/charts/scales.d.ts.map +1 -0
  160. package/dist/charts/scales.js +163 -0
  161. package/dist/charts/sizing.d.ts +12 -0
  162. package/dist/charts/sizing.d.ts.map +1 -0
  163. package/dist/charts/sizing.js +33 -0
  164. package/dist/charts/state.d.ts +17 -0
  165. package/dist/charts/state.d.ts.map +1 -0
  166. package/dist/charts/state.js +53 -0
  167. package/dist/charts/theme.d.ts +38 -19
  168. package/dist/charts/theme.d.ts.map +1 -1
  169. package/dist/charts/theme.js +48 -26
  170. package/dist/charts/types.d.ts +227 -0
  171. package/dist/charts/types.d.ts.map +1 -0
  172. package/dist/charts/types.js +4 -0
  173. package/dist/cli/audit-allows.d.ts +4 -17
  174. package/dist/cli/audit-allows.d.ts.map +1 -1
  175. package/dist/cli/config.d.ts +14 -43
  176. package/dist/cli/config.d.ts.map +1 -1
  177. package/dist/cli/doctor-upgrade.d.ts +31 -0
  178. package/dist/cli/doctor-upgrade.d.ts.map +1 -0
  179. package/dist/cli/doctor-upgrade.js +269 -0
  180. package/dist/cli/doctor.d.ts +13 -26
  181. package/dist/cli/doctor.d.ts.map +1 -1
  182. package/dist/cli/doctor.js +79 -8
  183. package/dist/cli/help.d.ts.map +1 -1
  184. package/dist/cli/help.js +2 -4
  185. package/dist/cli/index.d.ts +68 -135
  186. package/dist/cli/index.d.ts.map +1 -1
  187. package/dist/cli/index.js +89 -76
  188. package/dist/cli/init.d.ts.map +1 -1
  189. package/dist/cli/init.js +43 -27
  190. package/dist/cli/sync.d.ts +5 -21
  191. package/dist/cli/sync.d.ts.map +1 -1
  192. package/dist/cli/sync.js +4 -6
  193. package/dist/cli/tokens-css.d.ts +7 -28
  194. package/dist/cli/tokens-css.d.ts.map +1 -1
  195. package/dist/commands/ShortcutsHelp.d.ts.map +1 -1
  196. package/dist/commands/ShortcutsHelp.js +4 -5
  197. package/dist/commands/define-commands.d.ts +15 -31
  198. package/dist/commands/define-commands.d.ts.map +1 -1
  199. package/dist/commands/define-commands.js +1 -11
  200. package/dist/commands/define-overlays.d.ts +5 -19
  201. package/dist/commands/define-overlays.d.ts.map +1 -1
  202. package/dist/commands/define-overlays.js +3 -11
  203. package/dist/commands/index.d.ts +10 -40
  204. package/dist/commands/index.d.ts.map +1 -1
  205. package/dist/commands/index.js +9 -46
  206. package/dist/{notifications → commands/notifications}/bell.d.ts +1 -1
  207. package/dist/commands/notifications/bell.d.ts.map +1 -0
  208. package/dist/{notifications → commands/notifications}/center.d.ts +2 -2
  209. package/dist/commands/notifications/center.d.ts.map +1 -0
  210. package/dist/{notifications → commands/notifications}/center.js +2 -2
  211. package/dist/{notifications → commands/notifications}/define-notifications.d.ts +3 -3
  212. package/dist/commands/notifications/define-notifications.d.ts.map +1 -0
  213. package/dist/commands/notifications/notify.d.ts +44 -0
  214. package/dist/commands/notifications/notify.d.ts.map +1 -0
  215. package/dist/commands/notifications/notify.js +79 -0
  216. package/dist/{notifications → commands/notifications}/store.d.ts +2 -0
  217. package/dist/commands/notifications/store.d.ts.map +1 -0
  218. package/dist/{notifications → commands/notifications}/store.js +4 -0
  219. package/dist/commands/projectors.d.ts +1 -131
  220. package/dist/commands/projectors.d.ts.map +1 -1
  221. package/dist/commands/projectors.js +2 -73
  222. package/dist/commands/shell-bridge.d.ts +3 -3
  223. package/dist/commands/shortcut-format.d.ts +5 -4
  224. package/dist/commands/shortcut-format.d.ts.map +1 -1
  225. package/dist/common/errors.d.ts +3 -3
  226. package/dist/common/use-measured-widths.d.ts.map +1 -1
  227. package/dist/common/use-measured-widths.js +5 -3
  228. package/dist/common/validate.d.ts +2 -2
  229. package/dist/content/article-layout.d.ts.map +1 -1
  230. package/dist/content/article-layout.js +3 -3
  231. package/dist/content/article-model.d.ts +1 -46
  232. package/dist/content/article-model.d.ts.map +1 -1
  233. package/dist/content/article-model.js +1 -29
  234. package/dist/content/copy-action.d.ts +1 -1
  235. package/dist/content/glyphs.d.ts +1 -1
  236. package/dist/content/index.d.ts +11 -41
  237. package/dist/content/index.d.ts.map +1 -1
  238. package/dist/content/index.js +3 -35
  239. package/dist/content/markdown.d.ts +1 -1
  240. package/dist/content/markdown.d.ts.map +1 -1
  241. package/dist/content/markdown.js +1 -1
  242. package/dist/content/mermaid.d.ts.map +1 -1
  243. package/dist/content/mermaid.js +7 -7
  244. package/dist/content/slug.d.ts +1 -8
  245. package/dist/content/slug.d.ts.map +1 -1
  246. package/dist/content/slug.js +1 -8
  247. package/dist/content/url-hardening.d.ts +2 -2
  248. package/dist/content/url-hardening.d.ts.map +1 -1
  249. package/dist/content/url-hardening.js +2 -0
  250. package/dist/controls/actions.d.ts +16 -1
  251. package/dist/controls/actions.d.ts.map +1 -1
  252. package/dist/controls/enum-filter.d.ts +1 -1
  253. package/dist/controls/enum-filter.d.ts.map +1 -1
  254. package/dist/controls/filter-context.d.ts.map +1 -1
  255. package/dist/controls/filter-context.js +3 -1
  256. package/dist/controls/filter-set.js +4 -6
  257. package/dist/controls/form-layout.d.ts +1 -1
  258. package/dist/controls/form-layout.d.ts.map +1 -1
  259. package/dist/controls/form-layout.js +1 -1
  260. package/dist/controls/glyphs.d.ts +0 -2
  261. package/dist/controls/glyphs.d.ts.map +1 -1
  262. package/dist/controls/glyphs.js +0 -7
  263. package/dist/controls/index.d.ts +12 -17
  264. package/dist/controls/index.d.ts.map +1 -1
  265. package/dist/controls/index.js +5 -39
  266. package/dist/controls/multi-select-filter.d.ts +4 -3
  267. package/dist/controls/multi-select-filter.d.ts.map +1 -1
  268. package/dist/controls/number-filter.d.ts +4 -3
  269. package/dist/controls/number-filter.d.ts.map +1 -1
  270. package/dist/controls/number-filter.js +3 -1
  271. package/dist/controls/range-filter.d.ts +4 -3
  272. package/dist/controls/range-filter.d.ts.map +1 -1
  273. package/dist/controls/search-filter.d.ts +4 -3
  274. package/dist/controls/search-filter.d.ts.map +1 -1
  275. package/dist/controls/search-filter.js +19 -14
  276. package/dist/controls/select-filter.d.ts +4 -3
  277. package/dist/controls/select-filter.d.ts.map +1 -1
  278. package/dist/controls/sync-button.d.ts.map +1 -1
  279. package/dist/controls/sync-button.js +12 -15
  280. package/dist/controls/toggle-filter.d.ts +4 -3
  281. package/dist/controls/toggle-filter.d.ts.map +1 -1
  282. package/dist/controls/uncontrolled.d.ts +12 -0
  283. package/dist/controls/uncontrolled.d.ts.map +1 -0
  284. package/dist/controls/view-tabs.d.ts +2 -2
  285. package/dist/controls/view-tabs.d.ts.map +1 -1
  286. package/dist/controls-dates/index.d.ts +0 -1
  287. package/dist/controls-dates/index.d.ts.map +1 -1
  288. package/dist/dashboard/index.d.ts +7 -9
  289. package/dist/dashboard/index.d.ts.map +1 -1
  290. package/dist/dashboard/index.js +3 -23
  291. package/dist/dashboard/section.d.ts +4 -6
  292. package/dist/dashboard/section.d.ts.map +1 -1
  293. package/dist/dashboard/section.js +4 -10
  294. package/dist/dashboard/stat-card.d.ts +4 -4
  295. package/dist/dashboard/stat-card.d.ts.map +1 -1
  296. package/dist/dashboard/stat-card.js +3 -3
  297. package/dist/dashboard/widget-header.module.css +9 -7
  298. package/dist/dev-dock.d.ts.map +1 -1
  299. package/dist/dev-dock.js +6 -1
  300. package/dist/format/date.d.ts +0 -34
  301. package/dist/format/date.d.ts.map +1 -1
  302. package/dist/format/date.js +0 -54
  303. package/dist/format/index.d.ts +7 -22
  304. package/dist/format/index.d.ts.map +1 -1
  305. package/dist/format/index.js +2 -43
  306. package/dist/format/number.d.ts +3 -14
  307. package/dist/format/number.d.ts.map +1 -1
  308. package/dist/format/number.js +0 -13
  309. package/dist/format/shared.d.ts +2 -3
  310. package/dist/format/shared.d.ts.map +1 -1
  311. package/dist/forms/index.d.ts +0 -11
  312. package/dist/forms/index.d.ts.map +1 -1
  313. package/dist/forms/index.js +1 -14
  314. package/dist/guard/index.d.ts +6 -21
  315. package/dist/guard/index.d.ts.map +1 -1
  316. package/dist/guard/index.js +27 -115
  317. package/dist/guard/types.d.ts +7 -18
  318. package/dist/guard/types.d.ts.map +1 -1
  319. package/dist/index.d.ts +16 -48
  320. package/dist/index.d.ts.map +1 -1
  321. package/dist/index.js +21 -117
  322. package/dist/provider/create-router.d.ts +44 -0
  323. package/dist/provider/create-router.d.ts.map +1 -0
  324. package/dist/provider/create-router.js +62 -0
  325. package/dist/provider/hotkeys.d.ts +8 -0
  326. package/dist/provider/hotkeys.d.ts.map +1 -0
  327. package/dist/provider/hotkeys.js +50 -0
  328. package/dist/provider/index.d.ts +33 -110
  329. package/dist/provider/index.d.ts.map +1 -1
  330. package/dist/provider/index.js +182 -82
  331. package/dist/provider/lab-theme.d.ts.map +1 -1
  332. package/dist/provider/route-transition.d.ts +76 -0
  333. package/dist/provider/route-transition.d.ts.map +1 -0
  334. package/dist/provider/route-transition.js +98 -0
  335. package/dist/provider/spotlight-actions.d.ts +10 -0
  336. package/dist/provider/spotlight-actions.d.ts.map +1 -0
  337. package/dist/provider/spotlight-actions.js +55 -0
  338. package/dist/provider/test-router.d.ts +6 -0
  339. package/dist/provider/test-router.d.ts.map +1 -0
  340. package/dist/provider/test-router.js +18 -0
  341. package/dist/query-client.d.ts +4 -20
  342. package/dist/query-client.d.ts.map +1 -1
  343. package/dist/query-client.js +2 -2
  344. package/dist/router-tanstack/index.d.ts +18 -64
  345. package/dist/router-tanstack/index.d.ts.map +1 -1
  346. package/dist/router-tanstack/index.js +2 -16
  347. package/dist/router-tanstack/nav.d.ts +12 -1
  348. package/dist/router-tanstack/nav.d.ts.map +1 -1
  349. package/dist/router-tanstack/nav.js +8 -1
  350. package/dist/router-tanstack/search-store.d.ts +1 -1
  351. package/dist/router-tanstack/search-store.d.ts.map +1 -1
  352. package/dist/router-tanstack/use-nav.d.ts +8 -9
  353. package/dist/router-tanstack/use-nav.d.ts.map +1 -1
  354. package/dist/router-tanstack/use-nav.js +20 -1
  355. package/dist/shell/app-mobile-nav.d.ts.map +1 -1
  356. package/dist/shell/app-sidebar.js +1 -1
  357. package/dist/shell/index.d.ts +31 -10
  358. package/dist/shell/index.d.ts.map +1 -1
  359. package/dist/shell/index.js +14 -3
  360. package/dist/shell/page-aside.d.ts +2 -2
  361. package/dist/shell/page-aside.d.ts.map +1 -1
  362. package/dist/shell/page-aside.js +31 -12
  363. package/dist/shell/page-bar.d.ts +2 -2
  364. package/dist/shell/page-bar.d.ts.map +1 -1
  365. package/dist/shell/page-bar.js +1 -1
  366. package/dist/state.d.ts +10 -12
  367. package/dist/state.d.ts.map +1 -1
  368. package/dist/state.js +4 -6
  369. package/dist/styles.css +107 -7
  370. package/dist/surfaces.d.ts +28 -103
  371. package/dist/surfaces.d.ts.map +1 -1
  372. package/dist/surfaces.js +54 -143
  373. package/dist/{data → table}/data-table-state.d.ts +1 -1
  374. package/dist/table/data-table-state.d.ts.map +1 -0
  375. package/dist/{data → table}/data-table-state.js +4 -3
  376. package/dist/{data → table}/data-table.d.ts +28 -49
  377. package/dist/table/data-table.d.ts.map +1 -0
  378. package/dist/{data → table}/data-table.js +74 -60
  379. package/dist/table/index.d.ts +18 -0
  380. package/dist/table/index.d.ts.map +1 -0
  381. package/dist/{data/table.js → table/index.js} +1 -1
  382. package/dist/table/query-branch.d.ts.map +1 -0
  383. package/dist/table/table-features.d.ts +69 -0
  384. package/dist/table/table-features.d.ts.map +1 -0
  385. package/dist/table/table-features.js +49 -0
  386. package/dist/telemetry.d.ts +77 -0
  387. package/dist/telemetry.d.ts.map +1 -0
  388. package/dist/telemetry.js +33 -0
  389. package/dist/theme/index.d.ts +10 -21
  390. package/dist/theme/index.d.ts.map +1 -1
  391. package/dist/theme/index.js +3 -14
  392. package/dist/theme/theme-toggle.d.ts.map +1 -1
  393. package/dist/theme/theme-toggle.js +7 -33
  394. package/dist/theme/theme-toggle.module.css +30 -0
  395. package/dist/theme/theme-toggle.module.css.d.ts +10 -0
  396. package/dist/theme-lab/derive-controls.d.ts.map +1 -1
  397. package/dist/theme-lab/derive-controls.js +5 -3
  398. package/dist/theme-lab/derive-state.d.ts.map +1 -1
  399. package/dist/theme-lab/derive-state.js +2 -1
  400. package/dist/tokens/core.d.ts +360 -0
  401. package/dist/tokens/core.d.ts.map +1 -0
  402. package/dist/tokens/core.js +708 -0
  403. package/dist/tokens/derive.d.ts +1 -1
  404. package/dist/tokens/derive.d.ts.map +1 -1
  405. package/dist/tokens/index.d.ts +5 -373
  406. package/dist/tokens/index.d.ts.map +1 -1
  407. package/dist/tokens/index.js +8 -700
  408. package/dist/tokens/palette.d.ts +2 -6
  409. package/dist/tokens/palette.d.ts.map +1 -1
  410. package/dist/tokens/palette.js +1 -4
  411. package/dist/vite.d.ts +4 -3
  412. package/dist/vite.d.ts.map +1 -1
  413. package/llms.txt +43 -85
  414. package/package.json +77 -170
  415. package/src/agent/ai-sdk-transport.ts +57 -37
  416. package/src/{agent-chat → agent/chat}/composer.tsx +29 -30
  417. package/src/{agent-chat → agent/chat}/message-affordances.ts +8 -5
  418. package/src/{agent-chat → agent/chat}/thread-feed-row.tsx +30 -35
  419. package/src/{agent-chat → agent/chat}/thread-feed.tsx +40 -35
  420. package/src/{agent-chat → agent/chat}/thread-message.tsx +37 -35
  421. package/src/{agent-chat → agent/chat}/thread-outcome-card.tsx +5 -5
  422. package/src/{agent-chat → agent/chat}/tool-chip.tsx +12 -12
  423. package/src/{agent-chat → agent/chat}/use-keyboard-inset.ts +1 -1
  424. package/src/{agent-chat → agent/chat}/virtualize.ts +5 -5
  425. package/src/agent/error.ts +43 -0
  426. package/src/agent/foreign.ts +3 -2
  427. package/src/agent/history.ts +2 -107
  428. package/src/agent/id.ts +4 -5
  429. package/src/agent/index.ts +23 -112
  430. package/src/agent/outcome.ts +3 -56
  431. package/src/agent/part-list.tsx +3 -3
  432. package/src/agent/parts.ts +23 -22
  433. package/src/agent/run-committer.ts +64 -0
  434. package/src/agent/run-records.ts +147 -0
  435. package/src/agent/thread.ts +24 -231
  436. package/src/agent/transport.ts +6 -96
  437. package/src/agent/use-agent-thread-runs.ts +364 -199
  438. package/src/charts/BandStrip.tsx +276 -0
  439. package/src/charts/Bars.tsx +141 -0
  440. package/src/charts/CartesianChart.tsx +206 -0
  441. package/src/charts/ChartCard.tsx +178 -0
  442. package/src/charts/Donut.tsx +256 -0
  443. package/src/charts/DualPanel.tsx +326 -0
  444. package/src/charts/Heatmap.tsx +282 -0
  445. package/src/charts/Lines.tsx +151 -0
  446. package/src/charts/MirroredBars.tsx +303 -0
  447. package/src/charts/Sparkline.tsx +176 -0
  448. package/src/charts/StackedArea.tsx +80 -0
  449. package/src/charts/box.tsx +96 -0
  450. package/src/charts/card-context.ts +11 -0
  451. package/src/charts/chart-box.module.css +64 -0
  452. package/src/charts/chart-box.module.css.d.ts +12 -0
  453. package/src/charts/chart-card.module.css +25 -0
  454. package/src/charts/chart-card.module.css.d.ts +8 -0
  455. package/src/charts/chart-legend.module.css +38 -0
  456. package/src/charts/chart-legend.module.css.d.ts +10 -0
  457. package/src/charts/compile.ts +585 -0
  458. package/src/charts/cursor.ts +282 -0
  459. package/src/charts/curves.ts +111 -0
  460. package/src/charts/donut.module.css +54 -0
  461. package/src/charts/donut.module.css.d.ts +9 -0
  462. package/src/charts/host.tsx +60 -0
  463. package/src/charts/index.ts +41 -178
  464. package/src/charts/legend.tsx +204 -0
  465. package/src/charts/marks.ts +201 -0
  466. package/src/charts/panel.tsx +227 -0
  467. package/src/charts/scales.ts +237 -0
  468. package/src/charts/sizing.ts +47 -0
  469. package/src/charts/state.tsx +80 -0
  470. package/src/charts/theme.ts +65 -0
  471. package/src/charts/types.ts +242 -0
  472. package/src/cli/audit-allows.ts +8 -30
  473. package/src/cli/config.ts +14 -43
  474. package/src/cli/doctor-upgrade.ts +392 -0
  475. package/src/cli/doctor.ts +120 -68
  476. package/src/cli/help.ts +2 -4
  477. package/src/cli/index.ts +161 -276
  478. package/src/cli/init.ts +60 -37
  479. package/src/cli/sync.ts +13 -45
  480. package/src/cli/tokens-css.ts +7 -28
  481. package/src/commands/ShortcutsHelp.tsx +8 -9
  482. package/src/commands/define-commands.ts +16 -43
  483. package/src/commands/define-overlays.ts +12 -36
  484. package/src/commands/index.ts +11 -94
  485. package/src/{notifications → commands/notifications}/bell.tsx +2 -2
  486. package/src/{notifications → commands/notifications}/center.tsx +7 -5
  487. package/src/{notifications → commands/notifications}/define-notifications.ts +3 -3
  488. package/src/commands/notifications/notify.tsx +158 -0
  489. package/src/{notifications → commands/notifications}/store.ts +10 -2
  490. package/src/commands/projectors.ts +5 -225
  491. package/src/commands/shell-bridge.ts +5 -5
  492. package/src/commands/shortcut-format.ts +5 -4
  493. package/src/common/errors.ts +3 -3
  494. package/src/common/use-measured-widths.ts +6 -3
  495. package/src/common/validate.ts +2 -2
  496. package/src/content/article-layout.tsx +37 -38
  497. package/src/content/article-model.ts +1 -84
  498. package/src/content/copy-action.tsx +1 -1
  499. package/src/content/glyphs.tsx +1 -1
  500. package/src/content/index.ts +12 -83
  501. package/src/content/markdown.tsx +4 -3
  502. package/src/content/mermaid.tsx +9 -7
  503. package/src/content/slug.ts +1 -16
  504. package/src/content/url-hardening.ts +8 -2
  505. package/src/controls/actions.tsx +24 -1
  506. package/src/controls/enum-filter.tsx +1 -1
  507. package/src/controls/filter-context.tsx +3 -1
  508. package/src/controls/filter-set.tsx +5 -7
  509. package/src/controls/form-layout.tsx +2 -2
  510. package/src/controls/glyphs.tsx +0 -10
  511. package/src/controls/index.ts +13 -64
  512. package/src/controls/multi-select-filter.tsx +5 -4
  513. package/src/controls/number-filter.tsx +8 -4
  514. package/src/controls/range-filter.tsx +5 -4
  515. package/src/controls/search-filter.tsx +25 -19
  516. package/src/controls/select-filter.tsx +5 -4
  517. package/src/controls/sync-button.tsx +18 -20
  518. package/src/controls/toggle-filter.tsx +5 -4
  519. package/src/controls/uncontrolled.ts +12 -0
  520. package/src/controls/view-tabs.tsx +3 -3
  521. package/src/controls-dates/date-range-picker.tsx +1 -1
  522. package/src/controls-dates/index.ts +0 -1
  523. package/src/dashboard/index.ts +7 -48
  524. package/src/dashboard/section.tsx +11 -40
  525. package/src/dashboard/stat-card.tsx +14 -16
  526. package/src/dashboard/widget-header.module.css +9 -7
  527. package/src/dev-dock.tsx +14 -27
  528. package/src/format/date.ts +2 -92
  529. package/src/format/index.ts +7 -53
  530. package/src/format/number.ts +3 -26
  531. package/src/format/shared.ts +2 -3
  532. package/src/forms/index.ts +0 -23
  533. package/src/guard/index.ts +37 -192
  534. package/src/guard/types.ts +6 -19
  535. package/src/index.ts +30 -282
  536. package/src/provider/create-router.tsx +138 -0
  537. package/src/provider/hotkeys.ts +70 -0
  538. package/src/provider/index.tsx +260 -230
  539. package/src/provider/lab-theme.ts +3 -2
  540. package/src/provider/route-transition.ts +199 -0
  541. package/src/provider/spotlight-actions.tsx +69 -0
  542. package/src/provider/test-router.tsx +25 -0
  543. package/src/query-client.ts +4 -22
  544. package/src/router-tanstack/index.ts +18 -112
  545. package/src/router-tanstack/nav.ts +28 -2
  546. package/src/router-tanstack/search-store.ts +9 -2
  547. package/src/router-tanstack/use-nav.ts +47 -13
  548. package/src/shell/app-mobile-nav.tsx +3 -2
  549. package/src/shell/app-sidebar.tsx +1 -1
  550. package/src/shell/aside-docking.ts +1 -1
  551. package/src/shell/index.tsx +61 -20
  552. package/src/shell/page-aside.tsx +47 -23
  553. package/src/shell/page-bar.tsx +3 -3
  554. package/src/shell/page-title.tsx +1 -1
  555. package/src/state.ts +11 -37
  556. package/src/styles.css +107 -7
  557. package/src/surfaces.ts +56 -151
  558. package/src/{data → table}/data-table-state.ts +5 -4
  559. package/src/{data → table}/data-table.tsx +170 -161
  560. package/src/table/index.ts +18 -0
  561. package/src/table/table-features.ts +102 -0
  562. package/src/telemetry.ts +110 -0
  563. package/src/theme/index.ts +22 -47
  564. package/src/theme/theme-toggle.module.css +30 -0
  565. package/src/theme/theme-toggle.module.css.d.ts +10 -0
  566. package/src/theme/theme-toggle.tsx +15 -43
  567. package/src/theme-lab/derive-controls.tsx +5 -3
  568. package/src/theme-lab/derive-state.ts +2 -1
  569. package/src/tokens/core.ts +1163 -0
  570. package/src/tokens/derive.ts +1 -1
  571. package/src/tokens/index.ts +14 -1181
  572. package/src/tokens/palette.ts +3 -7
  573. package/src/vite.ts +3 -3
  574. package/agent/templates/CLAUDE-block.md.tpl +0 -40
  575. package/agent/templates/query-client.ts.tpl +0 -26
  576. package/dist/agent/adapter.d.ts +0 -150
  577. package/dist/agent/adapter.d.ts.map +0 -1
  578. package/dist/agent/adapter.js +0 -482
  579. package/dist/agent/use-agent-stream.d.ts +0 -35
  580. package/dist/agent/use-agent-stream.d.ts.map +0 -1
  581. package/dist/agent/use-agent-stream.js +0 -59
  582. package/dist/agent-chat/composer.d.ts.map +0 -1
  583. package/dist/agent-chat/index.d.ts +0 -31
  584. package/dist/agent-chat/index.d.ts.map +0 -1
  585. package/dist/agent-chat/index.js +0 -19
  586. package/dist/agent-chat/message-affordances.d.ts.map +0 -1
  587. package/dist/agent-chat/relative-time.d.ts.map +0 -1
  588. package/dist/agent-chat/thread-detail-panel.d.ts +0 -28
  589. package/dist/agent-chat/thread-detail-panel.d.ts.map +0 -1
  590. package/dist/agent-chat/thread-detail-panel.js +0 -115
  591. package/dist/agent-chat/thread-feed-row.d.ts.map +0 -1
  592. package/dist/agent-chat/thread-feed.d.ts.map +0 -1
  593. package/dist/agent-chat/thread-message.d.ts.map +0 -1
  594. package/dist/agent-chat/thread-outcome-card.d.ts.map +0 -1
  595. package/dist/agent-chat/thread-workspace.d.ts +0 -44
  596. package/dist/agent-chat/thread-workspace.d.ts.map +0 -1
  597. package/dist/agent-chat/thread-workspace.js +0 -153
  598. package/dist/agent-chat/tool-chip.d.ts.map +0 -1
  599. package/dist/agent-chat/use-keyboard-inset.d.ts.map +0 -1
  600. package/dist/agent-chat/virtualize.d.ts.map +0 -1
  601. package/dist/charts/cursor/resolve.d.ts +0 -75
  602. package/dist/charts/cursor/resolve.d.ts.map +0 -1
  603. package/dist/charts/cursor/resolve.js +0 -91
  604. package/dist/charts/cursor/scope.d.ts +0 -20
  605. package/dist/charts/cursor/scope.d.ts.map +0 -1
  606. package/dist/charts/cursor/scope.js +0 -20
  607. package/dist/charts/cursor/store.d.ts +0 -35
  608. package/dist/charts/cursor/store.d.ts.map +0 -1
  609. package/dist/charts/cursor/store.js +0 -25
  610. package/dist/charts/cursor/touch-pin.d.ts +0 -45
  611. package/dist/charts/cursor/touch-pin.d.ts.map +0 -1
  612. package/dist/charts/cursor/touch-pin.js +0 -79
  613. package/dist/charts/hooks/use-discrete-cursor.d.ts +0 -66
  614. package/dist/charts/hooks/use-discrete-cursor.d.ts.map +0 -1
  615. package/dist/charts/hooks/use-discrete-cursor.js +0 -198
  616. package/dist/charts/hooks/use-hysteresis.d.ts +0 -18
  617. package/dist/charts/hooks/use-hysteresis.d.ts.map +0 -1
  618. package/dist/charts/hooks/use-hysteresis.js +0 -12
  619. package/dist/charts/hooks/useBandPlot.d.ts +0 -145
  620. package/dist/charts/hooks/useBandPlot.d.ts.map +0 -1
  621. package/dist/charts/hooks/useBandPlot.js +0 -178
  622. package/dist/charts/hooks/useChartCursor.d.ts +0 -75
  623. package/dist/charts/hooks/useChartCursor.d.ts.map +0 -1
  624. package/dist/charts/hooks/useChartCursor.js +0 -200
  625. package/dist/charts/hooks/useChartSize.d.ts +0 -29
  626. package/dist/charts/hooks/useChartSize.d.ts.map +0 -1
  627. package/dist/charts/hooks/useChartSize.js +0 -8
  628. package/dist/charts/kinds/BandStrip.d.ts +0 -132
  629. package/dist/charts/kinds/BandStrip.d.ts.map +0 -1
  630. package/dist/charts/kinds/BandStrip.js +0 -241
  631. package/dist/charts/kinds/Bars.d.ts +0 -141
  632. package/dist/charts/kinds/Bars.d.ts.map +0 -1
  633. package/dist/charts/kinds/Bars.js +0 -343
  634. package/dist/charts/kinds/Donut.d.ts +0 -77
  635. package/dist/charts/kinds/Donut.d.ts.map +0 -1
  636. package/dist/charts/kinds/Donut.js +0 -245
  637. package/dist/charts/kinds/DualPanel.d.ts +0 -111
  638. package/dist/charts/kinds/DualPanel.d.ts.map +0 -1
  639. package/dist/charts/kinds/DualPanel.js +0 -471
  640. package/dist/charts/kinds/Heatmap.d.ts +0 -85
  641. package/dist/charts/kinds/Heatmap.d.ts.map +0 -1
  642. package/dist/charts/kinds/Heatmap.js +0 -243
  643. package/dist/charts/kinds/MirroredBars.d.ts +0 -98
  644. package/dist/charts/kinds/MirroredBars.d.ts.map +0 -1
  645. package/dist/charts/kinds/MirroredBars.js +0 -292
  646. package/dist/charts/kinds/MultiLine.d.ts +0 -87
  647. package/dist/charts/kinds/MultiLine.d.ts.map +0 -1
  648. package/dist/charts/kinds/MultiLine.js +0 -176
  649. package/dist/charts/kinds/StackedArea.d.ts +0 -73
  650. package/dist/charts/kinds/StackedArea.d.ts.map +0 -1
  651. package/dist/charts/kinds/StackedArea.js +0 -135
  652. package/dist/charts/kinds/ZonedLine.d.ts +0 -97
  653. package/dist/charts/kinds/ZonedLine.d.ts.map +0 -1
  654. package/dist/charts/kinds/ZonedLine.js +0 -155
  655. package/dist/charts/kinds/band-chrome.d.ts +0 -31
  656. package/dist/charts/kinds/band-chrome.d.ts.map +0 -1
  657. package/dist/charts/kinds/band-chrome.js +0 -71
  658. package/dist/charts/kinds/donut-layout.d.ts +0 -47
  659. package/dist/charts/kinds/donut-layout.d.ts.map +0 -1
  660. package/dist/charts/kinds/donut-layout.js +0 -52
  661. package/dist/charts/layout/auto-margin.d.ts +0 -122
  662. package/dist/charts/layout/auto-margin.d.ts.map +0 -1
  663. package/dist/charts/layout/auto-margin.js +0 -81
  664. package/dist/charts/layout/end-labels.d.ts +0 -64
  665. package/dist/charts/layout/end-labels.d.ts.map +0 -1
  666. package/dist/charts/layout/end-labels.js +0 -76
  667. package/dist/charts/layout/log-ticks.d.ts +0 -27
  668. package/dist/charts/layout/log-ticks.d.ts.map +0 -1
  669. package/dist/charts/layout/log-ticks.js +0 -42
  670. package/dist/charts/primitives/AreaGradient.d.ts +0 -18
  671. package/dist/charts/primitives/AreaGradient.d.ts.map +0 -1
  672. package/dist/charts/primitives/AreaGradient.js +0 -13
  673. package/dist/charts/primitives/Axes.d.ts +0 -83
  674. package/dist/charts/primitives/Axes.d.ts.map +0 -1
  675. package/dist/charts/primitives/Axes.js +0 -168
  676. package/dist/charts/primitives/CartesianChart.d.ts +0 -257
  677. package/dist/charts/primitives/CartesianChart.d.ts.map +0 -1
  678. package/dist/charts/primitives/CartesianChart.js +0 -549
  679. package/dist/charts/primitives/ChartCard.d.ts +0 -66
  680. package/dist/charts/primitives/ChartCard.d.ts.map +0 -1
  681. package/dist/charts/primitives/ChartCard.js +0 -143
  682. package/dist/charts/primitives/ChartFrame.d.ts +0 -156
  683. package/dist/charts/primitives/ChartFrame.d.ts.map +0 -1
  684. package/dist/charts/primitives/ChartFrame.js +0 -241
  685. package/dist/charts/primitives/ChartLegend.d.ts +0 -67
  686. package/dist/charts/primitives/ChartLegend.d.ts.map +0 -1
  687. package/dist/charts/primitives/ChartLegend.js +0 -292
  688. package/dist/charts/primitives/ChartPending.d.ts +0 -113
  689. package/dist/charts/primitives/ChartPending.d.ts.map +0 -1
  690. package/dist/charts/primitives/ChartPending.js +0 -117
  691. package/dist/charts/primitives/ChartTooltip.d.ts +0 -59
  692. package/dist/charts/primitives/ChartTooltip.d.ts.map +0 -1
  693. package/dist/charts/primitives/ChartTooltip.js +0 -197
  694. package/dist/charts/primitives/Crosshair.d.ts +0 -26
  695. package/dist/charts/primitives/Crosshair.d.ts.map +0 -1
  696. package/dist/charts/primitives/Crosshair.js +0 -23
  697. package/dist/charts/primitives/HatchPattern.d.ts +0 -31
  698. package/dist/charts/primitives/HatchPattern.d.ts.map +0 -1
  699. package/dist/charts/primitives/HatchPattern.js +0 -31
  700. package/dist/charts/primitives/HoverOverlay.d.ts +0 -45
  701. package/dist/charts/primitives/HoverOverlay.d.ts.map +0 -1
  702. package/dist/charts/primitives/HoverOverlay.js +0 -72
  703. package/dist/charts/primitives/HoverOverlay.module.css +0 -13
  704. package/dist/charts/primitives/HoverOverlay.module.css.d.ts +0 -8
  705. package/dist/charts/primitives/XZoneRects.d.ts +0 -54
  706. package/dist/charts/primitives/XZoneRects.d.ts.map +0 -1
  707. package/dist/charts/primitives/XZoneRects.js +0 -65
  708. package/dist/charts/primitives/ZoneRects.d.ts +0 -38
  709. package/dist/charts/primitives/ZoneRects.d.ts.map +0 -1
  710. package/dist/charts/primitives/ZoneRects.js +0 -30
  711. package/dist/charts/primitives/chart-card-context.d.ts +0 -33
  712. package/dist/charts/primitives/chart-card-context.d.ts.map +0 -1
  713. package/dist/charts/primitives/chart-card-context.js +0 -18
  714. package/dist/charts/primitives/chart-frame-layout.d.ts +0 -185
  715. package/dist/charts/primitives/chart-frame-layout.d.ts.map +0 -1
  716. package/dist/charts/primitives/chart-frame-layout.js +0 -175
  717. package/dist/charts/primitives/chart-layout.d.ts +0 -112
  718. package/dist/charts/primitives/chart-layout.d.ts.map +0 -1
  719. package/dist/charts/primitives/chart-layout.js +0 -175
  720. package/dist/charts/primitives/chart-tier.d.ts +0 -16
  721. package/dist/charts/primitives/chart-tier.d.ts.map +0 -1
  722. package/dist/charts/primitives/chart-tier.js +0 -44
  723. package/dist/charts/primitives/legend-disclosure.d.ts +0 -27
  724. package/dist/charts/primitives/legend-disclosure.d.ts.map +0 -1
  725. package/dist/charts/primitives/legend-disclosure.js +0 -153
  726. package/dist/charts/series.d.ts +0 -189
  727. package/dist/charts/series.d.ts.map +0 -1
  728. package/dist/charts/series.js +0 -84
  729. package/dist/charts/sparklines/BarSparkline.d.ts +0 -37
  730. package/dist/charts/sparklines/BarSparkline.d.ts.map +0 -1
  731. package/dist/charts/sparklines/BarSparkline.js +0 -53
  732. package/dist/charts/sparklines/LineSparkline.d.ts +0 -15
  733. package/dist/charts/sparklines/LineSparkline.d.ts.map +0 -1
  734. package/dist/charts/sparklines/LineSparkline.js +0 -51
  735. package/dist/charts/sparklines/index.d.ts +0 -3
  736. package/dist/charts/sparklines/index.d.ts.map +0 -1
  737. package/dist/charts/sparklines/index.js +0 -6
  738. package/dist/charts/utils/domain.d.ts +0 -35
  739. package/dist/charts/utils/domain.d.ts.map +0 -1
  740. package/dist/charts/utils/domain.js +0 -12
  741. package/dist/charts/utils/format.d.ts +0 -8
  742. package/dist/charts/utils/format.d.ts.map +0 -1
  743. package/dist/charts/utils/format.js +0 -20
  744. package/dist/charts/utils/measure-text.d.ts +0 -25
  745. package/dist/charts/utils/measure-text.d.ts.map +0 -1
  746. package/dist/charts/utils/measure-text.js +0 -64
  747. package/dist/charts/utils/ticks.d.ts +0 -103
  748. package/dist/charts/utils/ticks.d.ts.map +0 -1
  749. package/dist/charts/utils/ticks.js +0 -92
  750. package/dist/commands/overlays-mount.d.ts +0 -122
  751. package/dist/commands/overlays-mount.d.ts.map +0 -1
  752. package/dist/commands/overlays-mount.js +0 -125
  753. package/dist/commands/useCommandHotkeys.d.ts +0 -14
  754. package/dist/commands/useCommandHotkeys.d.ts.map +0 -1
  755. package/dist/commands/useCommandHotkeys.js +0 -45
  756. package/dist/content/article-actions.d.ts +0 -39
  757. package/dist/content/article-actions.d.ts.map +0 -1
  758. package/dist/content/article-actions.js +0 -28
  759. package/dist/content/article-card.d.ts +0 -58
  760. package/dist/content/article-card.d.ts.map +0 -1
  761. package/dist/content/article-card.js +0 -79
  762. package/dist/content/article-card.module.css +0 -111
  763. package/dist/content/mdx.d.ts +0 -20
  764. package/dist/content/mdx.d.ts.map +0 -1
  765. package/dist/content/mdx.js +0 -64
  766. package/dist/controls/compare-filter.d.ts +0 -42
  767. package/dist/controls/compare-filter.d.ts.map +0 -1
  768. package/dist/controls/compare-filter.js +0 -38
  769. package/dist/controls/slider-control.d.ts +0 -36
  770. package/dist/controls/slider-control.d.ts.map +0 -1
  771. package/dist/controls/slider-control.js +0 -64
  772. package/dist/dashboard/widget-grid.d.ts +0 -27
  773. package/dist/dashboard/widget-grid.d.ts.map +0 -1
  774. package/dist/dashboard/widget-grid.js +0 -40
  775. package/dist/dashboard/widget-grid.module.css +0 -69
  776. package/dist/data/data-table-state.d.ts.map +0 -1
  777. package/dist/data/data-table.d.ts.map +0 -1
  778. package/dist/data/query-branch.d.ts.map +0 -1
  779. package/dist/data/table.d.ts +0 -24
  780. package/dist/data/table.d.ts.map +0 -1
  781. package/dist/data/virtual-list.d.ts +0 -133
  782. package/dist/data/virtual-list.d.ts.map +0 -1
  783. package/dist/data/virtual-list.js +0 -157
  784. package/dist/data/virtual.d.ts +0 -21
  785. package/dist/data/virtual.d.ts.map +0 -1
  786. package/dist/data/virtual.js +0 -4
  787. package/dist/forms/FormErrorSummary.d.ts +0 -30
  788. package/dist/forms/FormErrorSummary.d.ts.map +0 -1
  789. package/dist/forms/FormErrorSummary.js +0 -30
  790. package/dist/forms/use-field-array.d.ts +0 -60
  791. package/dist/forms/use-field-array.d.ts.map +0 -1
  792. package/dist/forms/use-field-array.js +0 -20
  793. package/dist/forms/use-form-draft.d.ts +0 -76
  794. package/dist/forms/use-form-draft.d.ts.map +0 -1
  795. package/dist/forms/use-form-draft.js +0 -92
  796. package/dist/forms/use-form-submit.d.ts +0 -88
  797. package/dist/forms/use-form-submit.d.ts.map +0 -1
  798. package/dist/forms/use-form-submit.js +0 -63
  799. package/dist/notifications/bell.d.ts.map +0 -1
  800. package/dist/notifications/center.d.ts.map +0 -1
  801. package/dist/notifications/define-notifications.d.ts.map +0 -1
  802. package/dist/notifications/index.d.ts +0 -40
  803. package/dist/notifications/index.d.ts.map +0 -1
  804. package/dist/notifications/index.js +0 -54
  805. package/dist/notifications/mount-guard.d.ts +0 -8
  806. package/dist/notifications/mount-guard.d.ts.map +0 -1
  807. package/dist/notifications/mount-guard.js +0 -18
  808. package/dist/notifications/notify.d.ts +0 -149
  809. package/dist/notifications/notify.d.ts.map +0 -1
  810. package/dist/notifications/notify.js +0 -171
  811. package/dist/notifications/store.d.ts.map +0 -1
  812. package/dist/provider/connectivity-indicator.d.ts +0 -13
  813. package/dist/provider/connectivity-indicator.d.ts.map +0 -1
  814. package/dist/provider/connectivity-indicator.js +0 -205
  815. package/dist/provider/connectivity-provider.d.ts +0 -7
  816. package/dist/provider/connectivity-provider.d.ts.map +0 -1
  817. package/dist/provider/connectivity-provider.js +0 -128
  818. package/dist/provider/connectivity-types.d.ts +0 -36
  819. package/dist/provider/connectivity-types.d.ts.map +0 -1
  820. package/dist/provider/use-connectivity.d.ts +0 -3
  821. package/dist/provider/use-connectivity.d.ts.map +0 -1
  822. package/dist/provider/use-connectivity.js +0 -14
  823. package/dist/query-devtools.d.ts +0 -21
  824. package/dist/query-devtools.d.ts.map +0 -1
  825. package/dist/query-devtools.js +0 -13
  826. package/src/agent/adapter.ts +0 -945
  827. package/src/agent/use-agent-stream.ts +0 -154
  828. package/src/agent-chat/index.ts +0 -54
  829. package/src/agent-chat/thread-detail-panel.tsx +0 -201
  830. package/src/agent-chat/thread-workspace.tsx +0 -279
  831. package/src/charts/cursor/resolve.ts +0 -198
  832. package/src/charts/cursor/scope.tsx +0 -35
  833. package/src/charts/cursor/store.ts +0 -58
  834. package/src/charts/cursor/touch-pin.ts +0 -138
  835. package/src/charts/hooks/use-discrete-cursor.ts +0 -335
  836. package/src/charts/hooks/use-hysteresis.ts +0 -26
  837. package/src/charts/hooks/useBandPlot.ts +0 -383
  838. package/src/charts/hooks/useChartCursor.ts +0 -367
  839. package/src/charts/hooks/useChartSize.ts +0 -35
  840. package/src/charts/kinds/BandStrip.tsx +0 -449
  841. package/src/charts/kinds/Bars.tsx +0 -589
  842. package/src/charts/kinds/Donut.tsx +0 -368
  843. package/src/charts/kinds/DualPanel.tsx +0 -712
  844. package/src/charts/kinds/Heatmap.tsx +0 -396
  845. package/src/charts/kinds/MirroredBars.tsx +0 -469
  846. package/src/charts/kinds/MultiLine.tsx +0 -322
  847. package/src/charts/kinds/StackedArea.tsx +0 -267
  848. package/src/charts/kinds/ZonedLine.tsx +0 -301
  849. package/src/charts/kinds/band-chrome.tsx +0 -91
  850. package/src/charts/kinds/donut-layout.ts +0 -82
  851. package/src/charts/layout/auto-margin.ts +0 -242
  852. package/src/charts/layout/end-labels.ts +0 -135
  853. package/src/charts/layout/log-ticks.ts +0 -90
  854. package/src/charts/primitives/AreaGradient.tsx +0 -26
  855. package/src/charts/primitives/Axes.tsx +0 -271
  856. package/src/charts/primitives/CartesianChart.tsx +0 -1002
  857. package/src/charts/primitives/ChartCard.tsx +0 -280
  858. package/src/charts/primitives/ChartFrame.tsx +0 -493
  859. package/src/charts/primitives/ChartLegend.tsx +0 -422
  860. package/src/charts/primitives/ChartPending.tsx +0 -243
  861. package/src/charts/primitives/ChartTooltip.tsx +0 -265
  862. package/src/charts/primitives/Crosshair.tsx +0 -43
  863. package/src/charts/primitives/HatchPattern.tsx +0 -55
  864. package/src/charts/primitives/HoverOverlay.module.css +0 -13
  865. package/src/charts/primitives/HoverOverlay.module.css.d.ts +0 -8
  866. package/src/charts/primitives/HoverOverlay.tsx +0 -109
  867. package/src/charts/primitives/XZoneRects.tsx +0 -132
  868. package/src/charts/primitives/ZoneRects.tsx +0 -67
  869. package/src/charts/primitives/chart-card-context.ts +0 -46
  870. package/src/charts/primitives/chart-frame-layout.ts +0 -430
  871. package/src/charts/primitives/chart-layout.ts +0 -318
  872. package/src/charts/primitives/chart-tier.tsx +0 -76
  873. package/src/charts/primitives/legend-disclosure.tsx +0 -178
  874. package/src/charts/series.ts +0 -276
  875. package/src/charts/sparklines/BarSparkline.tsx +0 -94
  876. package/src/charts/sparklines/LineSparkline.tsx +0 -71
  877. package/src/charts/sparklines/index.ts +0 -2
  878. package/src/charts/theme.tsx +0 -53
  879. package/src/charts/utils/domain.ts +0 -41
  880. package/src/charts/utils/format.ts +0 -19
  881. package/src/charts/utils/measure-text.ts +0 -109
  882. package/src/charts/utils/ticks.ts +0 -239
  883. package/src/commands/overlays-mount.tsx +0 -333
  884. package/src/commands/useCommandHotkeys.ts +0 -114
  885. package/src/content/article-actions.ts +0 -72
  886. package/src/content/article-card.module.css +0 -111
  887. package/src/content/article-card.tsx +0 -174
  888. package/src/content/mdx.tsx +0 -127
  889. package/src/controls/compare-filter.tsx +0 -81
  890. package/src/controls/slider-control.tsx +0 -159
  891. package/src/dashboard/widget-grid.module.css +0 -69
  892. package/src/dashboard/widget-grid.tsx +0 -146
  893. package/src/data/table.ts +0 -39
  894. package/src/data/virtual-list.tsx +0 -356
  895. package/src/data/virtual.ts +0 -26
  896. package/src/forms/FormErrorSummary.tsx +0 -71
  897. package/src/forms/use-field-array.ts +0 -94
  898. package/src/forms/use-form-draft.ts +0 -262
  899. package/src/forms/use-form-submit.ts +0 -199
  900. package/src/notifications/index.ts +0 -88
  901. package/src/notifications/mount-guard.ts +0 -38
  902. package/src/notifications/notify.tsx +0 -379
  903. package/src/provider/connectivity-indicator.tsx +0 -267
  904. package/src/provider/connectivity-provider.tsx +0 -189
  905. package/src/provider/connectivity-types.ts +0 -42
  906. package/src/provider/use-connectivity.ts +0 -26
  907. package/src/query-devtools.tsx +0 -40
  908. /package/dist/{agent-chat → agent/chat}/message-affordances.js +0 -0
  909. /package/dist/{agent-chat → agent/chat}/relative-time.d.ts +0 -0
  910. /package/dist/{agent-chat → agent/chat}/relative-time.js +0 -0
  911. /package/dist/{agent-chat → agent/chat}/use-keyboard-inset.d.ts +0 -0
  912. /package/dist/{agent-chat → agent/chat}/virtualize.js +0 -0
  913. /package/dist/{notifications → commands/notifications}/bell.js +0 -0
  914. /package/dist/{notifications → commands/notifications}/define-notifications.js +0 -0
  915. /package/dist/{provider/connectivity-types.js → controls/uncontrolled.js} +0 -0
  916. /package/dist/{data → table}/data-table.module.css +0 -0
  917. /package/dist/{data → table}/data-table.module.css.d.ts +0 -0
  918. /package/dist/{data → table}/query-branch.d.ts +0 -0
  919. /package/dist/{data → table}/query-branch.js +0 -0
  920. /package/src/{agent-chat → agent/chat}/relative-time.ts +0 -0
  921. /package/src/{data → table}/data-table.module.css +0 -0
  922. /package/src/{data → table}/data-table.module.css.d.ts +0 -0
  923. /package/src/{data → table}/query-branch.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  /**
2
- * ./data — BasaltDataTable: a sortable data table over @tanstack/react-table, rendered with Mantine.
3
- * Optional peer: @tanstack/react-table >=8 <9.
2
+ * ./table — BasaltDataTable: a sortable data table over @tanstack/react-table v9, rendered with
3
+ * Mantine. Optional peer: @tanstack/react-table 9.2.8 (exact).
4
4
  *
5
5
  * Ships with opt-in chrome layered on top of the base sortable table: a filter/search toolbar
6
6
  * (global search + faceted column Selects + an actions slot), a pagination bar ("Showing X–Y of N"
@@ -9,8 +9,7 @@
9
9
  * exactly as before.
10
10
  *
11
11
  * @example
12
- * import { BasaltDataTable } from 'basalt-ui/data/table'
13
- * import { createColumnHelper } from '@tanstack/react-table'
12
+ * import { BasaltDataTable, createColumnHelper } from 'basalt-ui/table'
14
13
  *
15
14
  * type Row = { name: string; age: number }
16
15
  * const col = createColumnHelper<Row>()
@@ -50,6 +49,7 @@ import type {
50
49
  Column,
51
50
  ColumnDef,
52
51
  ColumnFiltersState,
52
+ ColumnVisibilityState,
53
53
  FilterFn,
54
54
  PaginationState,
55
55
  Row,
@@ -57,18 +57,11 @@ import type {
57
57
  RowSelectionState,
58
58
  SortingState,
59
59
  Table as TanstackTable,
60
- VisibilityState,
61
- } from '@tanstack/react-table'
62
- import {
63
- flexRender,
64
- getCoreRowModel,
65
- getFilteredRowModel,
66
- getPaginationRowModel,
67
- getSortedRowModel,
68
- useReactTable,
69
60
  } from '@tanstack/react-table'
61
+ import { constructFilterFn, FlexRender, useTable } from '@tanstack/react-table'
70
62
  import type { CSSProperties, MouseEvent as ReactMouseEvent, ReactNode, RefObject } from 'react'
71
63
  import { Fragment, useLayoutEffect, useMemo, useRef, useState } from 'react'
64
+ import { useDebouncedCallback } from '@mantine/hooks'
72
65
  import { cx } from '../common/props'
73
66
  import type { BasaltProps, SlotStylesProps } from '../common/props'
74
67
  import { BASALT_PREFIX } from '../common/errors'
@@ -86,7 +79,7 @@ import { EnumFilter } from '../controls/enum-filter'
86
79
  import { MultiSelectFilter } from '../controls/multi-select-filter'
87
80
  import { CtlSlot } from '../theme'
88
81
  import { alpha, VX } from '../tokens'
89
- import type { EnumField, FieldHandle, MultiField } from '../state'
82
+ import type { EnumField, FieldHandle, MultiField } from '../state/fields'
90
83
  import { WidgetHeader } from '../dashboard'
91
84
  import { ErrorState } from '../dashboard/query-state'
92
85
  import type { QueryStateLike } from '../dashboard/query-state'
@@ -98,49 +91,24 @@ import {
98
91
  useRowDisclosure,
99
92
  } from './data-table-state'
100
93
  import { dataQueryBranch } from './query-branch'
94
+ import { basaltTableFeatures } from './table-features'
95
+ import type { BasaltColumnDef, BasaltTableFeatures, DataTableAlign } from './table-features'
101
96
  import classes from './data-table.module.css'
102
97
 
103
98
  // ── Column alignment ──────────────────────────────────────────────────────────
104
99
 
105
- /** Horizontal alignment of a column's header AND its cells. */
106
- export type DataTableAlign = 'left' | 'center' | 'right'
107
-
108
- /**
109
- * Alignment lives on the column def's `meta`, not on a parallel prop array, so it travels with the
110
- * column it describes and survives reordering.
111
- *
112
- * Declared as a module augmentation of TanStack's own `ColumnMeta` so `meta: { aling: 'right' }` is
113
- * a TYPE error (excess-property check on the object literal) rather than a silently ignored key —
114
- * and a wrong VALUE (`'end'`, `'centre'`) throws at render. A misspelled alignment that quietly
115
- * left-aligns a money column is the class of defect that looks correct in review.
116
- */
117
- declare module '@tanstack/react-table' {
118
- // TData/TValue are TanStack's own parameters — required to match its declaration, unused here.
119
- // oxlint-disable-next-line no-unused-vars
120
- interface ColumnMeta<TData extends RowData, TValue> {
121
- align?: DataTableAlign
122
- /**
123
- * Opt OUT of the automatic mono-numeral cell style. The table applies it whenever the cell's
124
- * raw value is a number — which is right for a plain figure and wrong for a numeric accessor
125
- * whose `cell` renders its own chrome (a coloured `Text`, a `Badge`, a sparkline), because the
126
- * `<td>`'s mono font then overrides what the cell asked for.
127
- */
128
- numeral?: boolean
129
- /**
130
- * Fold priority for the measured column fold (`docs/CONTROLS-SPEC.md` §2): once the
131
- * table no longer fits its wrapper, the HIGHEST-numbered priority column folds first, moving
132
- * into a per-row disclosure instead of forcing the table into horizontal scroll. Unset columns
133
- * fall back to their declared position, so a bare `<BasaltDataTable data columns />` folds its
134
- * LAST column first — nothing regresses with no `meta.priority` set anywhere. See `foldOrder`.
135
- */
136
- priority?: number
137
- }
138
- }
100
+ // `meta.align` is typed by `BasaltColumnMeta` (`table-features.ts`); only the VALUE check lives here.
139
101
 
140
102
  const ALIGNMENTS: ReadonlySet<string> = new Set<DataTableAlign>(['left', 'center', 'right'])
141
103
 
142
- /** Reads `meta.align` off a column, throwing on a value that is not one of the three. */
143
- function resolveAlign<T>(column: Column<T, unknown>): DataTableAlign | undefined {
104
+ /**
105
+ * Reads `meta.align` off a column, throwing on a value that is not one of the three — the one
106
+ * check a type cannot make once a value arrives from an untyped caller. A misspelled alignment that
107
+ * quietly left-aligns a money column looks correct in review.
108
+ */
109
+ function resolveAlign<T extends RowData>(
110
+ column: Column<BasaltTableFeatures, T, unknown>,
111
+ ): DataTableAlign | undefined {
144
112
  const align = column.columnDef.meta?.align
145
113
  if (align === undefined) return undefined
146
114
  if (!ALIGNMENTS.has(align)) {
@@ -168,7 +136,7 @@ export type DataTableFacetOption = {
168
136
  * synthetic/derived column id (no matching key on `T`) still type-checks. Defaults to `unknown` so
169
137
  * a bare `DataTableFacet[]` / `DataTableColumnPinning` (no type argument) keeps working exactly as
170
138
  * before. Shared by {@link DataTableFacet}'s `columnId` and {@link DataTableColumnPinning}'s
171
- * `left`/`right`.
139
+ * `start`/`end`.
172
140
  */
173
141
  export type DataTableColumnId<T = unknown> = Extract<keyof T, string> | (string & {})
174
142
 
@@ -196,13 +164,12 @@ export type DataTableFacet<T = unknown> = {
196
164
 
197
165
  /**
198
166
  * Column ids pinned to each edge — the same `T`-derived id union as {@link DataTableFacet}'s
199
- * `columnId`, applied to TanStack's own `ColumnPinningState` shape (`{ left, right }`, each a bare
200
- * `string[]` unrelated to any row type). Structurally assignable to `ColumnPinningState`, so no
201
- * cast is needed where this flows into `useState<ColumnPinningState>`.
167
+ * `columnId`, applied to the `{ start, end }` shape. Not itself a TanStack `ColumnPinningState`: both edges are
168
+ * optional here, and `useDataTableState` normalises a missing edge to `[]` before the table sees it.
202
169
  */
203
170
  export type DataTableColumnPinning<T = unknown> = {
204
- left?: DataTableColumnId<T>[]
205
- right?: DataTableColumnId<T>[]
171
+ start?: DataTableColumnId<T>[]
172
+ end?: DataTableColumnId<T>[]
206
173
  }
207
174
 
208
175
  /**
@@ -233,8 +200,8 @@ function facetAllLabel<T>(facet: DataTableFacet<T>): string {
233
200
  * subscription needed, since the enclosing `BasaltDataTable` already re-renders on every
234
201
  * `columnFilters` change and this handle is rebuilt fresh each render alongside its column.
235
202
  */
236
- function facetEnumHandle<T>(
237
- column: Column<T, unknown>,
203
+ function facetEnumHandle<T extends RowData>(
204
+ column: Column<BasaltTableFeatures, T, unknown>,
238
205
  facet: DataTableFacet<T>,
239
206
  ): FieldHandle<EnumField<string>> {
240
207
  return {
@@ -263,8 +230,8 @@ function facetEnumHandle<T>(
263
230
  * single-select case, `MultiField`'s own fallback — an empty selection — already means "no
264
231
  * constraint", so no synthetic option is needed here.
265
232
  */
266
- function facetMultiHandle<T>(
267
- column: Column<T, unknown>,
233
+ function facetMultiHandle<T extends RowData>(
234
+ column: Column<BasaltTableFeatures, T, unknown>,
268
235
  facet: DataTableFacet<T>,
269
236
  ): FieldHandle<MultiField<string>> {
270
237
  return {
@@ -296,10 +263,10 @@ function facetMultiHandle<T>(
296
263
  * (`basaltViteConfig` defines `process.env.NODE_ENV`, so a production bundle constant-folds this
297
264
  * away), degrade to "no pill for this facet" in production.
298
265
  */
299
- function resolveFacetColumn<T>(
300
- table: TanstackTable<T>,
266
+ function resolveFacetColumn<T extends RowData>(
267
+ table: TanstackTable<BasaltTableFeatures, T>,
301
268
  facet: DataTableFacet<T>,
302
- ): Column<T, unknown> | undefined {
269
+ ): Column<BasaltTableFeatures, T, unknown> | undefined {
303
270
  const column = table.getColumn(facet.columnId)
304
271
  if (column) return column
305
272
  if (process.env.NODE_ENV !== 'production') {
@@ -315,6 +282,34 @@ function resolveFacetColumn<T>(
315
282
  return undefined
316
283
  }
317
284
 
285
+ /**
286
+ * The facet filters, built with `constructFilterFn` so `autoRemove` is part of the typed definition:
287
+ * a facet with nothing selected is dropped from `columnFilters` rather than kept as a no-op. They
288
+ * match the column value's STRING form exactly (a Select's option values are strings), which is why
289
+ * the built-in `includesString` auto-filter (substring) is never allowed to run on a facet column.
290
+ */
291
+ const facetAutoRemove = (value: unknown): boolean =>
292
+ value === null ||
293
+ value === undefined ||
294
+ value === '' ||
295
+ (Array.isArray(value) && value.length === 0)
296
+
297
+ const facetExact = constructFilterFn({
298
+ filter: (dataValue, filterValue: string | null | undefined) =>
299
+ filterValue === null || filterValue === undefined || filterValue === ''
300
+ ? true
301
+ : String(dataValue) === filterValue,
302
+ autoRemove: facetAutoRemove,
303
+ })
304
+
305
+ const facetAnyOf = constructFilterFn({
306
+ filter: (dataValue, filterValue: string[]) =>
307
+ !Array.isArray(filterValue) || filterValue.length === 0
308
+ ? true
309
+ : filterValue.includes(String(dataValue)),
310
+ autoRemove: facetAutoRemove,
311
+ })
312
+
318
313
  // ── Row selection ─────────────────────────────────────────────────────────────
319
314
 
320
315
  /**
@@ -332,7 +327,7 @@ const SELECT_COLUMN_ID = '__basalt_select__'
332
327
  * lives inside the row, and a row carrying `onRowActivate` opens a detail from a click — so without
333
328
  * it, ticking the box also navigated away from the table the tick was meant to act on.
334
329
  */
335
- function selectionColumn<T>(): ColumnDef<T, unknown> {
330
+ function selectionColumn<T extends RowData>(): ColumnDef<BasaltTableFeatures, T, unknown> {
336
331
  return {
337
332
  id: SELECT_COLUMN_ID,
338
333
  enableSorting: false,
@@ -407,14 +402,15 @@ export type BasaltDataTableSlot = 'root' | 'toolbar' | 'table' | 'footer'
407
402
  * emptyState: <Text c="dimmed">No results found.</Text>,
408
403
  * }
409
404
  */
410
- export type BasaltDataTableProps<T> = BasaltProps &
405
+ export type BasaltDataTableProps<T extends RowData> = BasaltProps &
411
406
  SlotStylesProps<BasaltDataTableSlot> & {
412
407
  // ── Header (WidgetHeader, docs/CONTROLS-SPEC.md §2.2) ──────────────────────────
413
408
 
414
409
  /**
415
- * Optional heading rendered above the toolbar via `WidgetHeader tier="widget"`. `count` always
416
- * reads `table.getRowCount()` (C11) — never a raw `data.length` — so it tracks the row model
417
- * (post-filter/-pagination) rather than the unfiltered input.
410
+ * Optional heading rendered above the toolbar via `WidgetHeader tier="widget"`. The count tag
411
+ * beside it is automatic, not a prop (there is no `count`): it reads `table.getRowCount()` (C11)
412
+ * — never a raw `data.length` — so it tracks the row model (post-filter/-pagination) rather
413
+ * than the unfiltered input.
418
414
  */
419
415
  title?: string
420
416
  /** Optional leading icon, forwarded to `WidgetHeader`. */
@@ -425,14 +421,12 @@ export type BasaltDataTableProps<T> = BasaltProps &
425
421
  /** Row data array. */
426
422
  data: T[]
427
423
  /**
428
- * Column definitions. Use `createColumnHelper<T>()` from `@tanstack/react-table`
424
+ * Column definitions. Use `createColumnHelper<T>()` from `basalt-ui/table`
429
425
  * for a typed accessor builder — `col.accessor('field', …)` columns sort by value.
430
426
  */
431
- // The cell-value type varies per column, so the array is heterogeneous in TValue. `any` here
432
- // is the TanStack-idiomatic escape (accessor columns infer their own TValue); row typing stays
433
- // exact via the `T` data generic.
434
- // oxlint-disable-next-line typescript/no-explicit-any -- TanStack-idiomatic heterogeneous column array
435
- columns: ColumnDef<T, any>[]
427
+ // The cell-value type varies per column, so the array is heterogeneous in TValue
428
+ // (`BasaltColumnDef` carries the `any`); row typing stays exact via the `T` data generic.
429
+ columns: BasaltColumnDef<T>[]
436
430
  /**
437
431
  * Enable column sorting via clickable headers. Client-side — the rows in `data` are what get
438
432
  * reordered.
@@ -728,15 +722,15 @@ export type BasaltDataTableProps<T> = BasaltProps &
728
722
  // ── Column pinning ────────────────────────────────────────────────────────────
729
723
 
730
724
  /**
731
- * Enables sticky left/right column pinning — pinned columns stick to the edge with a panel
725
+ * Enables sticky start/end column pinning — pinned columns stick to the edge with a panel
732
726
  * background and a hairline shadow separator while the table scrolls horizontally. Pin columns
733
- * via `initialColumnPinning` (`{ left: string[], right: string[] }`).
727
+ * via `initialColumnPinning` (`{ start: string[], end: string[] }`).
734
728
  * @default false
735
729
  * @example
736
- * <BasaltDataTable data={rows} columns={columns} enablePinning initialColumnPinning={{ left: ['name'] }} />
730
+ * <BasaltDataTable data={rows} columns={columns} enablePinning initialColumnPinning={{ start: ['name'] }} />
737
731
  */
738
732
  enablePinning?: boolean
739
- /** Initial column-pinning state — which column ids stick to the left/right edge. */
733
+ /** Initial column-pinning state — which column ids stick to the start/end edge. */
740
734
  initialColumnPinning?: DataTableColumnPinning<T>
741
735
 
742
736
  // ── Body chrome ─────────────────────────────────────────────────────────────
@@ -885,6 +879,8 @@ const TABLE_TOOLBAR_STYLE: CSSProperties = { flex: '0 1 auto', minWidth: 0 }
885
879
  * `w={220}` in a 302px column was half of the overflow above.
886
880
  */
887
881
  const SEARCH_WIDTH = 220
882
+ /** How long the global search waits after the last keystroke before filtering. */
883
+ const SEARCH_DEBOUNCE_MS = 250
888
884
  const TABLE_SEARCH_STYLE: CSSProperties = {
889
885
  flex: `0 1 ${SEARCH_WIDTH}px`,
890
886
  minWidth: '12ch',
@@ -895,26 +891,27 @@ const PAGE_SIZE_WIDTH = 116
895
891
 
896
892
  // ── Column pinning helpers ────────────────────────────────────────────────────
897
893
 
898
- // Merges the left/center/right header-group triad TanStack exposes for pinning into the single
899
- // render order (left → center → right) the header row needs — depth-indexed so grouped headers
894
+ // Merges the start/center/end header-group triad TanStack exposes for pinning into the single
895
+ // render order (start → center → end) the header row needs — depth-indexed so grouped headers
900
896
  // (multi-row) still line up.
901
- function getOrderedHeaderGroups<T>(table: TanstackTable<T>) {
902
- const left = table.getLeftHeaderGroups()
897
+ function getOrderedHeaderGroups<T extends RowData>(table: TanstackTable<BasaltTableFeatures, T>) {
898
+ const start = table.getStartHeaderGroups()
903
899
  const center = table.getCenterHeaderGroups()
904
- const right = table.getRightHeaderGroups()
900
+ const end = table.getEndHeaderGroups()
905
901
  return center.map((group, index) => ({
906
902
  ...group,
907
- headers: [...(left[index]?.headers ?? []), ...group.headers, ...(right[index]?.headers ?? [])],
903
+ headers: [...(start[index]?.headers ?? []), ...group.headers, ...(end[index]?.headers ?? [])],
908
904
  }))
909
905
  }
910
906
 
911
- // Sticky offset math (column.getStart('left') / getAfter('right')) is computed purely from the
907
+ // Sticky offset math (column.getStart('start') / getAfter('end')) is computed purely from the
912
908
  // pinned columns' own `getSize()`, so only pinned cells need an explicit width to keep the offsets
913
909
  // accurate — center columns stay naturally sized. The hairline shadow marks the edge column
914
- // touching the unpinned center (first right-pinned index 0 / last left-pinned index).
915
- function getPinnedCellStyle<T>(
916
- table: TanstackTable<T>,
917
- column: Column<T, unknown>,
910
+ // touching the unpinned center (first end-pinned index 0 / last start-pinned index). Offsets are
911
+ // logical insets, so `dir=rtl` mirrors them; the hairline shadow is a physical offset and does not.
912
+ function getPinnedCellStyle<T extends RowData>(
913
+ table: TanstackTable<BasaltTableFeatures, T>,
914
+ column: Column<BasaltTableFeatures, T, unknown>,
918
915
  ): CSSProperties | undefined {
919
916
  const pinned = column.getIsPinned()
920
917
  if (!pinned) return undefined
@@ -927,18 +924,18 @@ function getPinnedCellStyle<T>(
927
924
  maxWidth: size,
928
925
  backgroundColor: VX.surface.panel,
929
926
  }
930
- if (pinned === 'left') {
931
- const isEdge = column.getPinnedIndex() === table.getLeftLeafColumns().length - 1
927
+ if (pinned === 'start') {
928
+ const isEdge = column.getPinnedIndex() === table.getStartLeafColumns().length - 1
932
929
  return {
933
930
  ...shared,
934
- left: column.getStart('left'),
931
+ insetInlineStart: column.getStart('start'),
935
932
  boxShadow: isEdge ? `4px 0 6px -4px ${alpha(VX.ink, 0.18)}` : undefined,
936
933
  }
937
934
  }
938
935
  const isEdge = column.getPinnedIndex() === 0
939
936
  return {
940
937
  ...shared,
941
- right: column.getAfter('right'),
938
+ insetInlineEnd: column.getAfter('end'),
942
939
  boxShadow: isEdge ? `-4px 0 6px -4px ${alpha(VX.ink, 0.18)}` : undefined,
943
940
  }
944
941
  }
@@ -947,7 +944,9 @@ function getPinnedCellStyle<T>(
947
944
 
948
945
  /** The column id TanStack will resolve internally for this raw def — explicit `id`, else the
949
946
  * accessor key string. Mirrors the resolution `facetColumns` already relies on above. */
950
- function columnDefId<T>(column: ColumnDef<T, unknown>): string | undefined {
947
+ function columnDefId<T extends RowData>(
948
+ column: ColumnDef<BasaltTableFeatures, T, unknown>,
949
+ ): string | undefined {
951
950
  if (column.id !== undefined) return column.id
952
951
  return 'accessorKey' in column && typeof column.accessorKey === 'string'
953
952
  ? column.accessorKey
@@ -963,7 +962,9 @@ function columnDefId<T>(column: ColumnDef<T, unknown>): string | undefined {
963
962
  * `accessorFn` with no explicit `id`) is never a fold candidate — nothing downstream could
964
963
  * reliably re-identify it once hidden.
965
964
  */
966
- function foldOrder<T>(columns: readonly ColumnDef<T, unknown>[]): string[] {
965
+ function foldOrder<T extends RowData>(
966
+ columns: readonly ColumnDef<BasaltTableFeatures, T, unknown>[],
967
+ ): string[] {
967
968
  return columns
968
969
  .map((column, index) => ({
969
970
  id: columnDefId(column),
@@ -988,16 +989,26 @@ const FOLD_ID_ATTR = 'data-basalt-fold-id'
988
989
  * width, once anything is folded — fit `room`. A candidate with no measured width yet (never
989
990
  * rendered) is skipped rather than folded blind, since folding it would remove the one place its
990
991
  * width could ever be read from.
992
+ *
993
+ * Every width is a rounded integer (`offsetWidth`, `clientWidth`), and a table that fills its
994
+ * wrapper stretches its columns to sum to `room` exactly — so the rounded sum lands up to half a
995
+ * pixel per column over it, and a table that fits folded a column on hydration (a server-painted
996
+ * table whose cells then moved). The fit check forgives that rounding and nothing more: half a
997
+ * pixel for each measured width (the foldable columns AND `fixedCount`, the pinned / non-hiding
998
+ * ones `overhead` sums), plus half a pixel for `room`'s own rounding (the `+ 1` in the slack).
991
999
  */
992
1000
  export function planColumnFold(input: {
993
1001
  room: number
994
1002
  toggleWidth: number
995
1003
  overhead: number
1004
+ /** How many columns `overhead` sums, for the rounding slack. */
1005
+ fixedCount?: number
996
1006
  order: readonly string[]
997
1007
  widths: ReadonlyMap<string, number>
998
1008
  }): ReadonlySet<string> {
999
- const { room, toggleWidth, overhead, order, widths } = input
1009
+ const { room, toggleWidth, overhead, fixedCount = 0, order, widths } = input
1000
1010
  const known = order.filter((id) => widths.has(id))
1011
+ const roundingSlack = (known.length + fixedCount + 1) / 2
1001
1012
  let unfolded = overhead + known.reduce((sum, id) => sum + (widths.get(id) ?? 0), 0)
1002
1013
  const folded = new Set<string>()
1003
1014
  for (const id of known) {
@@ -1007,7 +1018,7 @@ export function planColumnFold(input: {
1007
1018
  // doc pins as the FIRST declared column (the last-declared one folds first).
1008
1019
  if (folded.size >= known.length - 1) break
1009
1020
  const withToggle = unfolded + (folded.size > 0 ? toggleWidth : 0)
1010
- if (withToggle <= room) break
1021
+ if (withToggle <= room + roundingSlack) break
1011
1022
  folded.add(id)
1012
1023
  unfolded -= widths.get(id) ?? 0
1013
1024
  }
@@ -1039,14 +1050,12 @@ function useColumnFold(input: {
1039
1050
  const wrapperRef = useRef<HTMLDivElement>(null)
1040
1051
  const [folded, setFolded] = useState<ReadonlySet<string>>(EMPTY_FOLD_SET)
1041
1052
  const orderRef = useRef(order)
1042
- orderRef.current = order
1043
1053
  const fixedIdsRef = useRef(fixedIds)
1044
- fixedIdsRef.current = fixedIds
1045
1054
  useLayoutEffect(() => {
1046
- if (!active || order.length === 0) {
1047
- setFolded((current) => (current.size === 0 ? current : EMPTY_FOLD_SET))
1048
- }
1049
- }, [active, order.length])
1055
+ orderRef.current = order
1056
+ fixedIdsRef.current = fixedIds
1057
+ })
1058
+ if ((!active || order.length === 0) && folded.size > 0) setFolded(EMPTY_FOLD_SET)
1050
1059
 
1051
1060
  useMeasuredWidths({
1052
1061
  resolveRoot: () => wrapperRef.current,
@@ -1074,6 +1083,7 @@ function useColumnFold(input: {
1074
1083
  // reads as one more `--vx-hit` control rather than a narrower afterthought.
1075
1084
  toggleWidth: HIT_COARSE,
1076
1085
  overhead,
1086
+ fixedCount: fixedIdsRef.current.length,
1077
1087
  order: orderRef.current,
1078
1088
  widths,
1079
1089
  })
@@ -1089,7 +1099,7 @@ function useColumnFold(input: {
1089
1099
  /** The label half of a folded column's disclosure row — its own header when it is a plain string
1090
1100
  * (the common case), else the column id, since a function/`ReactNode` header has no header
1091
1101
  * CONTEXT to render with here (this is a body row, not the `<thead>`). */
1092
- function columnLabel<T>(column: Column<T, unknown>): string {
1102
+ function columnLabel<T extends RowData>(column: Column<BasaltTableFeatures, T, unknown>): string {
1093
1103
  const header = column.columnDef.header
1094
1104
  return typeof header === 'string' ? header : column.id
1095
1105
  }
@@ -1097,11 +1107,11 @@ function columnLabel<T>(column: Column<T, unknown>): string {
1097
1107
  /** One row's folded columns as label/value pairs, directly under it. `row.getAllCells()` returns
1098
1108
  * every leaf cell regardless of visibility (unlike `getVisibleCells()`), so a folded column's own
1099
1109
  * `cell` renderer still draws here exactly as it would in the `<td>` it no longer occupies. */
1100
- function RowDisclosure<T>({
1110
+ function RowDisclosure<T extends RowData>({
1101
1111
  row,
1102
1112
  folded,
1103
1113
  }: {
1104
- row: Row<T>
1114
+ row: Row<BasaltTableFeatures, T>
1105
1115
  folded: ReadonlySet<string>
1106
1116
  }): ReactNode {
1107
1117
  const cells = row.getAllCells().filter((cell) => folded.has(cell.column.id))
@@ -1111,7 +1121,7 @@ function RowDisclosure<T>({
1111
1121
  <div key={cell.id} className={classes.foldDisclosureRow}>
1112
1122
  <Text className={classes.foldDisclosureLabel}>{columnLabel(cell.column)}</Text>
1113
1123
  <div className={classes.foldDisclosureValue}>
1114
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
1124
+ <FlexRender cell={cell} />
1115
1125
  </div>
1116
1126
  </div>
1117
1127
  ))}
@@ -1314,9 +1324,9 @@ function useMeasuredContainment(active: boolean): {
1314
1324
  * emptyState={<Text c="dimmed">No users found.</Text>}
1315
1325
  * />
1316
1326
  */
1317
- export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1318
- // F-ERR-1: without this, a table missing `data`/`columns` fails deep inside `useReactTable` as a
1319
- // raw `TypeError` caught by `BasaltErrorBoundary` — a blank subtree with no message naming either
1327
+ export function BasaltDataTable<T extends RowData>(props: BasaltDataTableProps<T>) {
1328
+ // F-ERR-1: without this, a table missing `data`/`columns` fails deep inside `useTable` as a
1329
+ // raw `TypeError` caught by `RootBoundary` — a blank subtree with no message naming either
1320
1330
  // prop.
1321
1331
  assertRequiredProps('BasaltDataTable', props, ['data', 'columns'])
1322
1332
  const {
@@ -1364,6 +1374,15 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1364
1374
  } = props
1365
1375
  const tableState = useDataTableState(props, pageSizeOptions[0] ?? 10)
1366
1376
  const { globalFilter, columnPinning, onGlobalFilterChange: handleGlobalFilterChange } = tableState
1377
+ // The input binds to a local draft so typing stays instant; the table (and `onGlobalFilterChange`)
1378
+ // only see the value once typing pauses. Invariant: the debounced commit is the ONLY writer of
1379
+ // `globalFilter`, so the draft never needs syncing back from it. `flushOnUnmount` delivers a
1380
+ // pending keystroke to `onGlobalFilterChange` rather than dropping it with the table.
1381
+ const [searchDraft, setSearchDraft] = useState(globalFilter)
1382
+ const commitSearch = useDebouncedCallback(handleGlobalFilterChange, {
1383
+ delay: SEARCH_DEBOUNCE_MS,
1384
+ flushOnUnmount: true,
1385
+ })
1367
1386
 
1368
1387
  // `stickyHeaderOffset` is DROPPED whenever the table owns a scroll container — see
1369
1388
  // `resolvedStickyHeaderOffset` below for why it is always wrong there. Dropping it silently is
@@ -1416,20 +1435,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1416
1435
  const id = columnDefId(column)
1417
1436
  const facet = id === undefined ? undefined : facetById.get(id)
1418
1437
  if (!facet) return column
1419
- const filterFn: FilterFn<T> = facet.multiple
1420
- ? (row, columnId, filterValue: string[]) =>
1421
- !Array.isArray(filterValue) || filterValue.length === 0
1422
- ? true
1423
- : filterValue.includes(String(row.getValue(columnId)))
1424
- : (row, columnId, filterValue: string) =>
1425
- filterValue === null || filterValue === undefined || filterValue === ''
1426
- ? true
1427
- : String(row.getValue(columnId)) === filterValue
1428
- filterFn.autoRemove = (value) =>
1429
- value === null ||
1430
- value === undefined ||
1431
- value === '' ||
1432
- (Array.isArray(value) && value.length === 0)
1438
+ const filterFn: FilterFn<BasaltTableFeatures, T> = facet.multiple ? facetAnyOf : facetExact
1433
1439
  return { ...column, filterFn }
1434
1440
  })
1435
1441
  }, [columns, facets])
@@ -1483,7 +1489,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1483
1489
  // column are excluded outright, not merely de-prioritized — both are the caller stating this
1484
1490
  // column must stay visible, the same declaration a fold candidate has no way to override.
1485
1491
  const { columnFoldOrder, columnFoldFixedIds } = useMemo(() => {
1486
- const pinnedIds = new Set([...(columnPinning.left ?? []), ...(columnPinning.right ?? [])])
1492
+ const pinnedIds = new Set([...columnPinning.start, ...columnPinning.end])
1487
1493
  const excluded = new Set(
1488
1494
  columns.flatMap((column) => {
1489
1495
  const id = columnDefId(column)
@@ -1498,20 +1504,23 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1498
1504
  }, [columns, columnPinning])
1499
1505
  // The card projection unmounts the table, so the fold and the containment wrapper go inactive with
1500
1506
  // it — their measuring effects re-attach to the remounted table when the width returns.
1501
- const projection = useCardProjection(renderCard !== undefined)
1502
- const columnFold = useColumnFold({
1503
- active: foldEligible && !projection.cards,
1507
+ const { cards: showCards, rootRef: projectionRootRef } = useCardProjection(
1508
+ renderCard !== undefined,
1509
+ )
1510
+ const { folded: foldedColumns, wrapperRef: foldWrapperRef } = useColumnFold({
1511
+ active: foldEligible && !showCards,
1504
1512
  order: columnFoldOrder,
1505
1513
  fixedIds: columnFoldFixedIds,
1506
1514
  })
1507
- const columnVisibility: VisibilityState = useMemo(
1508
- () => Object.fromEntries([...columnFold.folded].map((id) => [id, false])),
1509
- [columnFold.folded],
1515
+ const columnVisibility: ColumnVisibilityState = useMemo(
1516
+ () => Object.fromEntries([...foldedColumns].map((id) => [id, false])),
1517
+ [foldedColumns],
1510
1518
  )
1511
- const hasFolded = columnFold.folded.size > 0
1519
+ const hasFolded = foldedColumns.size > 0
1512
1520
  const foldRows = useRowDisclosure({ data, getRowId })
1513
1521
 
1514
- const table = useReactTable<T>({
1522
+ const table = useTable({
1523
+ features: basaltTableFeatures,
1515
1524
  data,
1516
1525
  columns: tableColumns,
1517
1526
  state: {
@@ -1533,19 +1542,16 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1533
1542
  onRowSelectionChange: tableState.onRowSelectionChange,
1534
1543
  }),
1535
1544
  ...(getRowId !== undefined && { getRowId }),
1536
- getCoreRowModel: getCoreRowModel(),
1537
- getSortedRowModel: getSortedRowModel(),
1538
- getFilteredRowModel: getFilteredRowModel(),
1539
- // Both row models stay installed and are BYPASSED by these flags, which is TanStack's own
1540
- // seam — so a degraded table renders `data` in the order and completeness the server sent it.
1541
- // Forced only by a BREACH, never by `enableSorting={false}` on its own: that pair still applies
1542
- // an `initialSorting` today (it disables the header control, not the row model) and a table
1543
- // that is not misreporting has no business losing it.
1545
+ // Every row model is registered on the feature set (v9 has no per-render switch) and BYPASSED by
1546
+ // these flags, which is TanStack's own seam — so a degraded table renders `data` in the order
1547
+ // and completeness the server sent it. Sorting/filtering are forced only by a BREACH, never by
1548
+ // `enableSorting={false}` on its own: that pair still applies an `initialSorting` today (it
1549
+ // disables the header control, not the row model) and a table that is not misreporting has no
1550
+ // business losing it. Pagination is bypassed whenever it is not enabled, or is server-driven.
1544
1551
  manualSorting: manualSorting || breaches.includes('sorting'),
1545
1552
  manualFiltering: manualFiltering || breaches.includes('filtering'),
1553
+ manualPagination: !enablePagination || manualPagination,
1546
1554
  ...(enablePagination && {
1547
- getPaginationRowModel: getPaginationRowModel(),
1548
- manualPagination,
1549
1555
  ...(manualPagination && rowCount !== undefined && { rowCount }),
1550
1556
  ...(manualPagination && pageCount !== undefined && { pageCount }),
1551
1557
  }),
@@ -1569,7 +1575,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1569
1575
  // the prepended checkbox column, one more again for the fold-disclosure toggle once anything has
1570
1576
  // folded — a stale count left the empty state and the error row short of the header.
1571
1577
  const columnCount =
1572
- columns.length + (enableRowSelection ? 1 : 0) + (hasFolded ? 1 : 0) - columnFold.folded.size
1578
+ columns.length + (enableRowSelection ? 1 : 0) + (hasFolded ? 1 : 0) - foldedColumns.size
1573
1579
 
1574
1580
  // `getSelectedRowModel()` is TanStack's own memo, so its `rows` array keeps its identity until
1575
1581
  // the selection or the row model actually moves — which is what makes both memos below hold.
@@ -1611,7 +1617,9 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1611
1617
  // `useMeasuredContainment` drives instead: bare while the table fits, `overflow-x: auto` once it
1612
1618
  // does not. Its docblock carries the full accounting.
1613
1619
  const pageStickyHeader = !scrolls && stickyHeader === true
1614
- const containment = useMeasuredContainment(pageStickyHeader && !projection.cards)
1620
+ const { wrapperRef: containmentRef, contained } = useMeasuredContainment(
1621
+ pageStickyHeader && !showCards,
1622
+ )
1615
1623
  const resolvedStickyHeaderOffset = scrolls ? undefined : stickyHeaderOffset
1616
1624
 
1617
1625
  // The error branch the table did not have (components audit #3) carries the query's OWN `refetch`
@@ -1686,9 +1694,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1686
1694
  ...pinnedStyle,
1687
1695
  }}
1688
1696
  >
1689
- {header.isPlaceholder
1690
- ? null
1691
- : flexRender(header.column.columnDef.header, header.getContext())}
1697
+ {header.isPlaceholder ? null : <FlexRender header={header} />}
1692
1698
  {canSort && <SortIndicator direction={sorted} />}
1693
1699
  </Table.Th>
1694
1700
  )
@@ -1719,9 +1725,9 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1719
1725
  rows.map((row) => {
1720
1726
  const cells = enablePinning
1721
1727
  ? [
1722
- ...row.getLeftVisibleCells(),
1728
+ ...row.getStartVisibleCells(),
1723
1729
  ...row.getCenterVisibleCells(),
1724
- ...row.getRightVisibleCells(),
1730
+ ...row.getEndVisibleCells(),
1725
1731
  ]
1726
1732
  : row.getVisibleCells()
1727
1733
  const rowExpanded = hasFolded && foldRows.expanded.has(row.id)
@@ -1765,7 +1771,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1765
1771
  ...pinnedStyle,
1766
1772
  }}
1767
1773
  >
1768
- {flexRender(cell.column.columnDef.cell, cell.getContext())}
1774
+ <FlexRender cell={cell} />
1769
1775
  </Table.Td>
1770
1776
  )
1771
1777
  })}
@@ -1773,7 +1779,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1773
1779
  {rowExpanded && (
1774
1780
  <Table.Tr id={`${row.id}-fold`} className={classes.foldDisclosureRowTr}>
1775
1781
  <Table.Td colSpan={columnCount} className={classes.foldDisclosureCell}>
1776
- <RowDisclosure row={row} folded={columnFold.folded} />
1782
+ <RowDisclosure row={row} folded={foldedColumns} />
1777
1783
  </Table.Td>
1778
1784
  </Table.Tr>
1779
1785
  )}
@@ -1804,7 +1810,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1804
1810
  </Stack>
1805
1811
  )
1806
1812
 
1807
- const paginationState = table.getState().pagination
1813
+ const paginationState = table.state.pagination
1808
1814
  // The CURRENT page size is always an option, even when it is not in `pageSizeOptions`. Mantine's
1809
1815
  // Select renders EMPTY when its `value` matches no row, so a table opened at
1810
1816
  // `initialPagination.pageSize: 5` against the default `[10, 25, 50, 100]` showed a blank
@@ -1818,7 +1824,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1818
1824
 
1819
1825
  return (
1820
1826
  <div
1821
- ref={projection.rootRef}
1827
+ ref={projectionRootRef}
1822
1828
  className={cx(classNames?.root, className)}
1823
1829
  {...(style !== undefined && { style })}
1824
1830
  >
@@ -1861,8 +1867,11 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1861
1867
  style={TABLE_SEARCH_STYLE}
1862
1868
  placeholder={globalFilterPlaceholder}
1863
1869
  leftSection={searchIcon}
1864
- value={globalFilter}
1865
- onChange={(event) => handleGlobalFilterChange(event.currentTarget.value)}
1870
+ value={searchDraft}
1871
+ onChange={(event) => {
1872
+ setSearchDraft(event.currentTarget.value)
1873
+ commitSearch(event.currentTarget.value)
1874
+ }}
1866
1875
  />
1867
1876
  )}
1868
1877
  {showFacets && (
@@ -1895,7 +1904,7 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1895
1904
  {bulkBarActions !== undefined && (
1896
1905
  <BulkActionBar count={selectedRows.length} actions={bulkBarActions} />
1897
1906
  )}
1898
- {projection.cards ? (
1907
+ {showCards ? (
1899
1908
  maxHeight === undefined ? (
1900
1909
  renderCardList()
1901
1910
  ) : (
@@ -1915,16 +1924,16 @@ export function BasaltDataTable<T>(props: BasaltDataTableProps<T>) {
1915
1924
  // `maxHeight`-only included: a vertical cap is orthogonal to column width, so a
1916
1925
  // `stickyHeader` + `maxHeight` table (the pairing this package's own docs recommend) still
1917
1926
  // folds instead of silently regressing to horizontal scroll. A plain block box, so it
1918
- // constrains nothing on its own; `columnFold.wrapperRef` only reads it.
1919
- <div ref={columnFold.wrapperRef} className={classes.foldWrapper}>
1927
+ // constrains nothing on its own; `foldWrapperRef` only reads it.
1928
+ <div ref={foldWrapperRef} className={classes.foldWrapper}>
1920
1929
  {pageStickyHeader ? (
1921
1930
  // Pinning takes this wrapper too — a pinned column's offsets are `position: sticky` on
1922
1931
  // the cells and need no overflow box of their own, so the `overflow-x: auto` Box that
1923
1932
  // used to sit here was the exact inert-sticky defect this shape exists to avoid.
1924
1933
  <div
1925
- ref={containment.wrapperRef}
1934
+ ref={containmentRef}
1926
1935
  className={classes.containment}
1927
- data-contained={containment.contained ? 'true' : 'false'}
1936
+ data-contained={contained ? 'true' : 'false'}
1928
1937
  >
1929
1938
  {tableNode}
1930
1939
  </div>