basalt-ui 1.27.0 → 1.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1245) hide show
  1. package/AGENTS.md +28 -35
  2. package/CHANGELOG.md +72 -0
  3. package/MIGRATING.md +759 -22
  4. package/README.md +56 -69
  5. package/agent/rules/basalt-batteries.md +60 -168
  6. package/agent/rules/basalt-charts.md +56 -75
  7. package/agent/rules/basalt-controls.md +81 -87
  8. package/agent/rules/basalt-mantine.md +64 -98
  9. package/agent/rules/basalt-state.md +42 -60
  10. package/agent/rules/basalt-tokens.md +46 -67
  11. package/agent/skills/basalt-app/SKILL.md +2 -0
  12. package/agent/templates/CLAUDE-block.md.tpl +14 -14
  13. package/configs/oxlint-plugin.js +964 -33
  14. package/configs/oxlint-plugin.test.ts +902 -2
  15. package/configs/oxlint.json +6 -0
  16. package/dist/agent/ai-sdk-transport.d.ts.map +1 -1
  17. package/dist/agent/ai-sdk-transport.js +7 -4
  18. package/dist/agent/coalesce.d.ts.map +1 -1
  19. package/dist/agent/coalesce.js +2 -1
  20. package/dist/agent/merge.d.ts.map +1 -1
  21. package/dist/agent/merge.js +2 -1
  22. package/dist/agent/part-list.d.ts.map +1 -1
  23. package/dist/agent/part-list.js +2 -0
  24. package/dist/agent/stick-to-bottom.d.ts +3 -6
  25. package/dist/agent/stick-to-bottom.d.ts.map +1 -1
  26. package/dist/agent/stick-to-bottom.js +6 -3
  27. package/dist/agent/transport.d.ts +13 -2
  28. package/dist/agent/transport.d.ts.map +1 -1
  29. package/dist/agent/use-agent-thread-runs.d.ts +12 -1
  30. package/dist/agent/use-agent-thread-runs.d.ts.map +1 -1
  31. package/dist/agent/use-agent-thread-runs.js +20 -6
  32. package/dist/agent-chat/composer.d.ts +6 -2
  33. package/dist/agent-chat/composer.d.ts.map +1 -1
  34. package/dist/agent-chat/composer.js +49 -33
  35. package/dist/agent-chat/index.d.ts +1 -1
  36. package/dist/agent-chat/index.d.ts.map +1 -1
  37. package/dist/agent-chat/relative-time.d.ts +0 -9
  38. package/dist/agent-chat/relative-time.d.ts.map +1 -1
  39. package/dist/agent-chat/relative-time.js +2 -1
  40. package/dist/agent-chat/thread-detail-panel.d.ts +3 -2
  41. package/dist/agent-chat/thread-detail-panel.d.ts.map +1 -1
  42. package/dist/agent-chat/thread-detail-panel.js +9 -6
  43. package/dist/agent-chat/thread-feed-row.d.ts +32 -6
  44. package/dist/agent-chat/thread-feed-row.d.ts.map +1 -1
  45. package/dist/agent-chat/thread-feed-row.js +61 -26
  46. package/dist/agent-chat/thread-feed.d.ts +13 -2
  47. package/dist/agent-chat/thread-feed.d.ts.map +1 -1
  48. package/dist/agent-chat/thread-feed.js +16 -7
  49. package/dist/agent-chat/thread-message.d.ts +4 -3
  50. package/dist/agent-chat/thread-message.d.ts.map +1 -1
  51. package/dist/agent-chat/thread-message.js +70 -31
  52. package/dist/agent-chat/thread-outcome-card.d.ts +3 -2
  53. package/dist/agent-chat/thread-outcome-card.d.ts.map +1 -1
  54. package/dist/agent-chat/thread-outcome-card.js +9 -2
  55. package/dist/agent-chat/thread-workspace.d.ts +7 -2
  56. package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
  57. package/dist/agent-chat/thread-workspace.js +62 -29
  58. package/dist/agent-chat/tool-chip.d.ts +3 -2
  59. package/dist/agent-chat/tool-chip.d.ts.map +1 -1
  60. package/dist/agent-chat/tool-chip.js +7 -2
  61. package/dist/agent-chat/virtualize.d.ts +39 -0
  62. package/dist/agent-chat/virtualize.d.ts.map +1 -1
  63. package/dist/agent-chat/virtualize.js +15 -0
  64. package/dist/charts/hooks/useBandPlot.d.ts.map +1 -1
  65. package/dist/charts/hooks/useBandPlot.js +15 -8
  66. package/dist/charts/index.d.ts +11 -10
  67. package/dist/charts/index.d.ts.map +1 -1
  68. package/dist/charts/index.js +53 -9
  69. package/dist/charts/kinds/BandStrip.d.ts +10 -7
  70. package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
  71. package/dist/charts/kinds/BandStrip.js +12 -7
  72. package/dist/charts/kinds/Bars.d.ts +13 -9
  73. package/dist/charts/kinds/Bars.d.ts.map +1 -1
  74. package/dist/charts/kinds/Bars.js +37 -11
  75. package/dist/charts/kinds/Donut.d.ts +6 -5
  76. package/dist/charts/kinds/Donut.d.ts.map +1 -1
  77. package/dist/charts/kinds/Donut.js +19 -2
  78. package/dist/charts/kinds/DualPanel.d.ts +9 -6
  79. package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
  80. package/dist/charts/kinds/DualPanel.js +37 -9
  81. package/dist/charts/kinds/Heatmap.d.ts +10 -6
  82. package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
  83. package/dist/charts/kinds/Heatmap.js +58 -31
  84. package/dist/charts/kinds/MirroredBars.d.ts +6 -5
  85. package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
  86. package/dist/charts/kinds/MirroredBars.js +9 -2
  87. package/dist/charts/kinds/MultiLine.d.ts +11 -6
  88. package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
  89. package/dist/charts/kinds/MultiLine.js +24 -15
  90. package/dist/charts/kinds/StackedArea.d.ts +18 -8
  91. package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
  92. package/dist/charts/kinds/StackedArea.js +29 -4
  93. package/dist/charts/kinds/ZonedLine.d.ts +13 -11
  94. package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
  95. package/dist/charts/kinds/ZonedLine.js +33 -23
  96. package/dist/charts/layout/auto-margin.d.ts +65 -8
  97. package/dist/charts/layout/auto-margin.d.ts.map +1 -1
  98. package/dist/charts/layout/auto-margin.js +45 -10
  99. package/dist/charts/layout/log-ticks.d.ts +27 -0
  100. package/dist/charts/layout/log-ticks.d.ts.map +1 -0
  101. package/dist/charts/layout/log-ticks.js +42 -0
  102. package/dist/charts/primitives/Axes.d.ts +32 -4
  103. package/dist/charts/primitives/Axes.d.ts.map +1 -1
  104. package/dist/charts/primitives/Axes.js +49 -7
  105. package/dist/charts/primitives/CartesianChart.d.ts +45 -7
  106. package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
  107. package/dist/charts/primitives/CartesianChart.js +86 -28
  108. package/dist/charts/primitives/ChartCard.d.ts +45 -4
  109. package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
  110. package/dist/charts/primitives/ChartCard.js +70 -21
  111. package/dist/charts/primitives/ChartFrame.d.ts +30 -4
  112. package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
  113. package/dist/charts/primitives/ChartFrame.js +52 -15
  114. package/dist/charts/primitives/ChartLegend.d.ts +13 -2
  115. package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
  116. package/dist/charts/primitives/ChartLegend.js +33 -13
  117. package/dist/charts/primitives/ChartPending.d.ts +85 -6
  118. package/dist/charts/primitives/ChartPending.d.ts.map +1 -1
  119. package/dist/charts/primitives/ChartPending.js +100 -6
  120. package/dist/charts/primitives/ChartTooltip.d.ts +7 -0
  121. package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
  122. package/dist/charts/primitives/ChartTooltip.js +18 -5
  123. package/dist/charts/primitives/Crosshair.d.ts +3 -0
  124. package/dist/charts/primitives/Crosshair.d.ts.map +1 -1
  125. package/dist/charts/primitives/Crosshair.js +3 -1
  126. package/dist/charts/primitives/chart-frame-layout.d.ts +95 -0
  127. package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -0
  128. package/dist/charts/primitives/chart-frame-layout.js +89 -0
  129. package/dist/charts/primitives/chart-tier.d.ts +16 -0
  130. package/dist/charts/primitives/chart-tier.d.ts.map +1 -0
  131. package/dist/charts/primitives/chart-tier.js +20 -0
  132. package/dist/charts/series.d.ts +55 -1
  133. package/dist/charts/series.d.ts.map +1 -1
  134. package/dist/charts/series.js +27 -1
  135. package/dist/charts/sparklines/BarSparkline.d.ts +3 -3
  136. package/dist/charts/sparklines/BarSparkline.d.ts.map +1 -1
  137. package/dist/charts/sparklines/BarSparkline.js +9 -3
  138. package/dist/charts/sparklines/LineSparkline.d.ts +3 -3
  139. package/dist/charts/sparklines/LineSparkline.d.ts.map +1 -1
  140. package/dist/charts/sparklines/LineSparkline.js +15 -3
  141. package/dist/charts/sparklines/index.d.ts +2 -2
  142. package/dist/charts/sparklines/index.d.ts.map +1 -1
  143. package/dist/charts/utils/format.d.ts +7 -4
  144. package/dist/charts/utils/format.d.ts.map +1 -1
  145. package/dist/charts/utils/format.js +17 -24
  146. package/dist/charts/utils/ticks.d.ts +81 -2
  147. package/dist/charts/utils/ticks.d.ts.map +1 -1
  148. package/dist/charts/utils/ticks.js +54 -4
  149. package/dist/cli/audit-allows.d.ts +24 -0
  150. package/dist/cli/audit-allows.d.ts.map +1 -0
  151. package/dist/cli/audit-allows.js +240 -0
  152. package/dist/cli/check-theme.d.ts +10 -0
  153. package/dist/cli/check-theme.d.ts.map +1 -0
  154. package/dist/cli/check-theme.js +139 -0
  155. package/dist/cli/doctor.d.ts +47 -0
  156. package/dist/cli/doctor.d.ts.map +1 -0
  157. package/dist/cli/doctor.js +197 -0
  158. package/dist/cli/guard-hook.d.ts +9 -0
  159. package/dist/cli/guard-hook.d.ts.map +1 -0
  160. package/dist/cli/guard-hook.js +93 -0
  161. package/dist/cli/help.d.ts +9 -0
  162. package/dist/cli/help.d.ts.map +1 -0
  163. package/dist/cli/help.js +53 -0
  164. package/dist/cli/index.d.ts +360 -270
  165. package/dist/cli/index.d.ts.map +1 -1
  166. package/dist/cli/index.js +85 -1901
  167. package/dist/cli/init.d.ts +4 -0
  168. package/dist/cli/init.d.ts.map +1 -0
  169. package/dist/cli/init.js +165 -0
  170. package/dist/cli/sync.d.ts +43 -0
  171. package/dist/cli/sync.d.ts.map +1 -0
  172. package/dist/cli/sync.js +206 -0
  173. package/dist/cli/tokens-css.d.ts +51 -0
  174. package/dist/cli/tokens-css.d.ts.map +1 -0
  175. package/dist/cli/tokens-css.js +165 -0
  176. package/dist/commands/ShortcutsHelp.d.ts +3 -2
  177. package/dist/commands/ShortcutsHelp.d.ts.map +1 -1
  178. package/dist/commands/ShortcutsHelp.js +8 -2
  179. package/dist/commands/define-commands.d.ts.map +1 -1
  180. package/dist/commands/define-commands.js +2 -2
  181. package/dist/commands/define-overlays.d.ts +102 -0
  182. package/dist/commands/define-overlays.d.ts.map +1 -1
  183. package/dist/commands/define-overlays.js +102 -2
  184. package/dist/commands/index.d.ts +12 -2
  185. package/dist/commands/index.d.ts.map +1 -1
  186. package/dist/commands/index.js +9 -1
  187. package/dist/commands/overlays-mount.d.ts +16 -11
  188. package/dist/commands/overlays-mount.d.ts.map +1 -1
  189. package/dist/commands/overlays-mount.js +23 -14
  190. package/dist/commands/shell-bridge.d.ts +57 -0
  191. package/dist/commands/shell-bridge.d.ts.map +1 -0
  192. package/dist/commands/shell-bridge.js +32 -0
  193. package/dist/common/errors.d.ts +69 -0
  194. package/dist/common/errors.d.ts.map +1 -0
  195. package/dist/common/errors.js +64 -0
  196. package/dist/common/index.d.ts +17 -0
  197. package/dist/common/index.d.ts.map +1 -0
  198. package/dist/common/index.js +35 -0
  199. package/dist/common/is-dev.d.ts +3 -0
  200. package/dist/common/is-dev.d.ts.map +1 -0
  201. package/dist/common/is-dev.js +6 -0
  202. package/dist/{motion/index.d.ts → common/motion.d.ts} +1 -1
  203. package/dist/common/motion.d.ts.map +1 -0
  204. package/dist/common/props.d.ts +63 -0
  205. package/dist/common/props.d.ts.map +1 -0
  206. package/dist/common/props.js +6 -0
  207. package/dist/common/query-state-like.d.ts +43 -0
  208. package/dist/common/query-state-like.d.ts.map +1 -0
  209. package/dist/common/query-state-like.js +20 -0
  210. package/dist/common/refs.d.ts +29 -0
  211. package/dist/common/refs.d.ts.map +1 -0
  212. package/dist/common/refs.js +29 -0
  213. package/dist/common/scroll-parent.d.ts +23 -0
  214. package/dist/common/scroll-parent.d.ts.map +1 -0
  215. package/dist/common/scroll-parent.js +21 -0
  216. package/dist/common/validate.d.ts +38 -0
  217. package/dist/common/validate.d.ts.map +1 -0
  218. package/dist/common/validate.js +36 -0
  219. package/dist/content/article-layout.module.css +11 -4
  220. package/dist/content/callout.d.ts +8 -4
  221. package/dist/content/callout.d.ts.map +1 -1
  222. package/dist/content/callout.js +15 -8
  223. package/dist/content/guide.d.ts +5 -4
  224. package/dist/content/guide.d.ts.map +1 -1
  225. package/dist/content/guide.js +13 -4
  226. package/dist/content/heading-anchor.d.ts +24 -2
  227. package/dist/content/heading-anchor.d.ts.map +1 -1
  228. package/dist/content/heading-anchor.js +23 -9
  229. package/dist/content/index.d.ts.map +1 -1
  230. package/dist/content/markdown.d.ts +3 -4
  231. package/dist/content/markdown.d.ts.map +1 -1
  232. package/dist/content/markdown.js +3 -4
  233. package/dist/content/prose.module.css +9 -7
  234. package/dist/content/reading-progress.d.ts +10 -4
  235. package/dist/content/reading-progress.d.ts.map +1 -1
  236. package/dist/content/reading-progress.js +26 -10
  237. package/dist/content/slug.d.ts +4 -0
  238. package/dist/content/slug.d.ts.map +1 -1
  239. package/dist/content/toc.d.ts +11 -0
  240. package/dist/content/toc.d.ts.map +1 -1
  241. package/dist/content/toc.js +23 -10
  242. package/dist/controls/actions.d.ts +50 -7
  243. package/dist/controls/actions.d.ts.map +1 -1
  244. package/dist/controls/actions.js +39 -8
  245. package/dist/controls/compare-filter.d.ts +3 -2
  246. package/dist/controls/compare-filter.d.ts.map +1 -1
  247. package/dist/controls/compare-filter.js +17 -2
  248. package/dist/controls/control-group.d.ts +3 -3
  249. package/dist/controls/control-group.d.ts.map +1 -1
  250. package/dist/controls/control-group.js +9 -2
  251. package/dist/controls/controls.module.css +169 -186
  252. package/dist/controls/controls.module.css.d.ts +9 -11
  253. package/dist/controls/enum-filter.d.ts +3 -2
  254. package/dist/controls/enum-filter.d.ts.map +1 -1
  255. package/dist/controls/enum-filter.js +28 -13
  256. package/dist/controls/filter-context.d.ts +8 -4
  257. package/dist/controls/filter-context.d.ts.map +1 -1
  258. package/dist/controls/filter-pill.d.ts +3 -3
  259. package/dist/controls/filter-pill.d.ts.map +1 -1
  260. package/dist/controls/filter-pill.js +4 -1
  261. package/dist/controls/filter-set.d.ts +3 -2
  262. package/dist/controls/filter-set.d.ts.map +1 -1
  263. package/dist/controls/filter-set.js +66 -41
  264. package/dist/controls/filter-sheet.d.ts +20 -80
  265. package/dist/controls/filter-sheet.d.ts.map +1 -1
  266. package/dist/controls/filter-sheet.js +9 -95
  267. package/dist/controls/index.d.ts +2 -0
  268. package/dist/controls/index.d.ts.map +1 -1
  269. package/dist/controls/index.js +4 -0
  270. package/dist/controls/multi-select-filter.d.ts +18 -2
  271. package/dist/controls/multi-select-filter.d.ts.map +1 -1
  272. package/dist/controls/multi-select-filter.js +122 -20
  273. package/dist/controls/number-filter.d.ts +7 -5
  274. package/dist/controls/number-filter.d.ts.map +1 -1
  275. package/dist/controls/number-filter.js +40 -11
  276. package/dist/controls/panel-row.d.ts +132 -0
  277. package/dist/controls/panel-row.d.ts.map +1 -0
  278. package/dist/controls/panel-row.js +173 -0
  279. package/dist/controls/panel-row.module.css +86 -0
  280. package/dist/controls/panel-row.module.css.d.ts +13 -0
  281. package/dist/controls/range-filter.d.ts +2 -1
  282. package/dist/controls/range-filter.d.ts.map +1 -1
  283. package/dist/controls/range-filter.js +57 -35
  284. package/dist/controls/search-filter.d.ts +3 -2
  285. package/dist/controls/search-filter.d.ts.map +1 -1
  286. package/dist/controls/search-filter.js +25 -10
  287. package/dist/controls/select-filter.d.ts +2 -1
  288. package/dist/controls/select-filter.d.ts.map +1 -1
  289. package/dist/controls/select-filter.js +4 -0
  290. package/dist/controls/slider-control.d.ts +36 -0
  291. package/dist/controls/slider-control.d.ts.map +1 -0
  292. package/dist/controls/slider-control.js +64 -0
  293. package/dist/controls/sync-button.d.ts +3 -2
  294. package/dist/controls/sync-button.d.ts.map +1 -1
  295. package/dist/controls/sync-button.js +16 -3
  296. package/dist/controls/toggle-filter.d.ts +3 -2
  297. package/dist/controls/toggle-filter.d.ts.map +1 -1
  298. package/dist/controls/toggle-filter.js +28 -11
  299. package/dist/controls/view-tabs.d.ts +3 -2
  300. package/dist/controls/view-tabs.d.ts.map +1 -1
  301. package/dist/controls/view-tabs.js +43 -11
  302. package/dist/controls-dates/date-range-picker.d.ts +1 -1
  303. package/dist/controls-dates/date-range-picker.d.ts.map +1 -1
  304. package/dist/controls-dates/date-range-picker.js +6 -1
  305. package/dist/dashboard/delta-badge.d.ts +18 -6
  306. package/dist/dashboard/delta-badge.d.ts.map +1 -1
  307. package/dist/dashboard/delta-badge.js +33 -1
  308. package/dist/dashboard/empty-state.d.ts +8 -4
  309. package/dist/dashboard/empty-state.d.ts.map +1 -1
  310. package/dist/dashboard/empty-state.js +36 -6
  311. package/dist/dashboard/index.d.ts +9 -5
  312. package/dist/dashboard/index.d.ts.map +1 -1
  313. package/dist/dashboard/index.js +13 -1
  314. package/dist/dashboard/query-state.d.ts +39 -27
  315. package/dist/dashboard/query-state.d.ts.map +1 -1
  316. package/dist/dashboard/query-state.js +109 -58
  317. package/dist/dashboard/section.d.ts +58 -0
  318. package/dist/dashboard/section.d.ts.map +1 -0
  319. package/dist/dashboard/section.js +118 -0
  320. package/dist/{section → dashboard}/section.module.css +11 -0
  321. package/dist/dashboard/settings-section.d.ts +19 -9
  322. package/dist/dashboard/settings-section.d.ts.map +1 -1
  323. package/dist/dashboard/settings-section.js +75 -26
  324. package/dist/dashboard/stat-card.d.ts +44 -38
  325. package/dist/dashboard/stat-card.d.ts.map +1 -1
  326. package/dist/dashboard/stat-card.js +56 -43
  327. package/dist/dashboard/stat-card.module.css +46 -31
  328. package/dist/dashboard/stat-card.module.css.d.ts +1 -0
  329. package/dist/dashboard/stat-group.d.ts +41 -0
  330. package/dist/dashboard/stat-group.d.ts.map +1 -0
  331. package/dist/dashboard/stat-group.js +30 -0
  332. package/dist/dashboard/stat-group.module.css +66 -0
  333. package/dist/dashboard/stat-group.module.css.d.ts +8 -0
  334. package/dist/dashboard/widget-grid.d.ts +27 -0
  335. package/dist/dashboard/widget-grid.d.ts.map +1 -0
  336. package/dist/dashboard/widget-grid.js +41 -0
  337. package/dist/dashboard/widget-grid.module.css +53 -0
  338. package/dist/dashboard/widget-grid.module.css.d.ts +9 -0
  339. package/dist/dashboard/widget-header.d.ts +132 -0
  340. package/dist/dashboard/widget-header.d.ts.map +1 -0
  341. package/dist/{widget-header → dashboard}/widget-header.js +42 -27
  342. package/dist/{widget-header → dashboard}/widget-header.module.css +72 -7
  343. package/dist/data/data-table.d.ts +151 -12
  344. package/dist/data/data-table.d.ts.map +1 -1
  345. package/dist/data/data-table.js +385 -139
  346. package/dist/data/data-table.module.css +64 -0
  347. package/dist/data/data-table.module.css.d.ts +11 -0
  348. package/dist/data/query-branch.d.ts +28 -0
  349. package/dist/data/query-branch.d.ts.map +1 -0
  350. package/dist/data/query-branch.js +10 -0
  351. package/dist/data/table.d.ts +2 -2
  352. package/dist/data/table.d.ts.map +1 -1
  353. package/dist/data/table.js +2 -16
  354. package/dist/data/virtual-list.d.ts +65 -6
  355. package/dist/data/virtual-list.d.ts.map +1 -1
  356. package/dist/data/virtual-list.js +89 -38
  357. package/dist/data/virtual.d.ts +4 -4
  358. package/dist/data/virtual.d.ts.map +1 -1
  359. package/dist/dev-dock.d.ts +28 -0
  360. package/dist/dev-dock.d.ts.map +1 -0
  361. package/dist/dev-dock.js +85 -0
  362. package/dist/format/date.d.ts +62 -0
  363. package/dist/format/date.d.ts.map +1 -0
  364. package/dist/format/date.js +106 -0
  365. package/dist/format/index.d.ts +39 -0
  366. package/dist/format/index.d.ts.map +1 -0
  367. package/dist/format/index.js +54 -0
  368. package/dist/format/measure.d.ts +15 -0
  369. package/dist/format/measure.d.ts.map +1 -0
  370. package/dist/format/measure.js +16 -0
  371. package/dist/format/number.d.ts +69 -0
  372. package/dist/format/number.d.ts.map +1 -0
  373. package/dist/format/number.js +62 -0
  374. package/dist/format/shared.d.ts +27 -0
  375. package/dist/format/shared.d.ts.map +1 -0
  376. package/dist/format/shared.js +29 -0
  377. package/dist/forms/FormErrorSummary.d.ts +4 -3
  378. package/dist/forms/FormErrorSummary.d.ts.map +1 -1
  379. package/dist/forms/FormErrorSummary.js +6 -4
  380. package/dist/forms/create-form.d.ts +2 -2
  381. package/dist/forms/field.d.ts +33 -9
  382. package/dist/forms/field.d.ts.map +1 -1
  383. package/dist/forms/field.js +7 -6
  384. package/dist/forms/form-layout.d.ts +142 -0
  385. package/dist/forms/form-layout.d.ts.map +1 -0
  386. package/dist/forms/form-layout.js +110 -0
  387. package/dist/forms/form-layout.module.css +145 -0
  388. package/dist/forms/form-layout.module.css.d.ts +20 -0
  389. package/dist/forms/form-state.d.ts +42 -0
  390. package/dist/forms/form-state.d.ts.map +1 -0
  391. package/dist/forms/form-state.js +26 -0
  392. package/dist/forms/index.d.ts +22 -6
  393. package/dist/forms/index.d.ts.map +1 -1
  394. package/dist/forms/index.js +19 -4
  395. package/dist/forms/use-field-array.d.ts +60 -0
  396. package/dist/forms/use-field-array.d.ts.map +1 -0
  397. package/dist/forms/use-field-array.js +20 -0
  398. package/dist/forms/use-form-draft.d.ts +25 -10
  399. package/dist/forms/use-form-draft.d.ts.map +1 -1
  400. package/dist/forms/use-form-draft.js +55 -18
  401. package/dist/forms/use-form-submit.d.ts +88 -0
  402. package/dist/forms/use-form-submit.d.ts.map +1 -0
  403. package/dist/forms/use-form-submit.js +63 -0
  404. package/dist/guard/index.d.ts +2 -9
  405. package/dist/guard/index.d.ts.map +1 -1
  406. package/dist/guard/index.js +38 -28
  407. package/dist/guard/types.d.ts +8 -10
  408. package/dist/guard/types.d.ts.map +1 -1
  409. package/dist/index.d.ts +21 -14
  410. package/dist/index.d.ts.map +1 -1
  411. package/dist/index.js +40 -6
  412. package/dist/notifications/bell.d.ts +3 -2
  413. package/dist/notifications/bell.d.ts.map +1 -1
  414. package/dist/notifications/bell.js +73 -56
  415. package/dist/notifications/center.d.ts +15 -4
  416. package/dist/notifications/center.d.ts.map +1 -1
  417. package/dist/notifications/center.js +5 -2
  418. package/dist/notifications/define-notifications.d.ts +56 -14
  419. package/dist/notifications/define-notifications.d.ts.map +1 -1
  420. package/dist/notifications/define-notifications.js +2 -1
  421. package/dist/notifications/index.d.ts +11 -7
  422. package/dist/notifications/index.d.ts.map +1 -1
  423. package/dist/notifications/index.js +5 -3
  424. package/dist/notifications/mount-guard.d.ts +8 -0
  425. package/dist/notifications/mount-guard.d.ts.map +1 -0
  426. package/dist/notifications/mount-guard.js +19 -0
  427. package/dist/notifications/notify.d.ts +58 -1
  428. package/dist/notifications/notify.d.ts.map +1 -1
  429. package/dist/notifications/notify.js +46 -2
  430. package/dist/notifications/store.d.ts +7 -0
  431. package/dist/notifications/store.d.ts.map +1 -1
  432. package/dist/provider/connectivity-indicator.d.ts +13 -0
  433. package/dist/provider/connectivity-indicator.d.ts.map +1 -0
  434. package/dist/{connectivity → provider}/connectivity-indicator.js +3 -1
  435. package/dist/{connectivity → provider}/connectivity-provider.d.ts +1 -1
  436. package/dist/provider/connectivity-provider.d.ts.map +1 -0
  437. package/dist/{connectivity → provider}/connectivity-provider.js +4 -1
  438. package/dist/{connectivity/types.d.ts → provider/connectivity-types.d.ts} +3 -3
  439. package/dist/provider/connectivity-types.d.ts.map +1 -0
  440. package/dist/provider/error-fallback.module.css +21 -0
  441. package/dist/provider/error-fallback.module.css.d.ts +9 -0
  442. package/dist/provider/index.d.ts +29 -13
  443. package/dist/provider/index.d.ts.map +1 -1
  444. package/dist/provider/index.js +82 -34
  445. package/dist/provider/lab-theme.d.ts.map +1 -1
  446. package/dist/provider/lab-theme.js +2 -1
  447. package/dist/provider/use-connectivity.d.ts +3 -0
  448. package/dist/provider/use-connectivity.d.ts.map +1 -0
  449. package/dist/query-client.d.ts +63 -0
  450. package/dist/query-client.d.ts.map +1 -0
  451. package/dist/query-client.js +33 -0
  452. package/dist/{query/devtools.d.ts → query-devtools.d.ts} +2 -2
  453. package/dist/query-devtools.d.ts.map +1 -0
  454. package/dist/{query/devtools.js → query-devtools.js} +1 -0
  455. package/dist/register.d.ts +17 -3
  456. package/dist/register.d.ts.map +1 -1
  457. package/dist/router-tanstack/index.d.ts +4 -7
  458. package/dist/router-tanstack/index.d.ts.map +1 -1
  459. package/dist/router-tanstack/index.js +1 -9
  460. package/dist/router-tanstack/nav.d.ts +1 -1
  461. package/dist/router-tanstack/nav.d.ts.map +1 -1
  462. package/dist/router-tanstack/search-store.d.ts +3 -6
  463. package/dist/router-tanstack/search-store.d.ts.map +1 -1
  464. package/dist/router-tanstack/search-store.js +1 -1
  465. package/dist/router-tanstack/use-nav.d.ts +1 -1
  466. package/dist/router-tanstack/use-nav.d.ts.map +1 -1
  467. package/dist/router-tanstack/use-nav.js +1 -1
  468. package/dist/shell/account-types.d.ts +5 -2
  469. package/dist/shell/account-types.d.ts.map +1 -1
  470. package/dist/shell/app-brand.d.ts +13 -0
  471. package/dist/shell/app-brand.d.ts.map +1 -0
  472. package/dist/shell/app-brand.js +94 -0
  473. package/dist/shell/app-brand.module.css +109 -0
  474. package/dist/shell/app-brand.module.css.d.ts +14 -0
  475. package/dist/shell/app-breadcrumbs.d.ts +5 -3
  476. package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
  477. package/dist/shell/app-breadcrumbs.js +33 -22
  478. package/dist/shell/app-header.module.css +10 -5
  479. package/dist/shell/app-main.module.css +118 -0
  480. package/dist/shell/app-main.module.css.d.ts +11 -0
  481. package/dist/shell/app-mobile-nav.d.ts +4 -3
  482. package/dist/shell/app-mobile-nav.d.ts.map +1 -1
  483. package/dist/shell/app-mobile-nav.js +53 -17
  484. package/dist/shell/app-mobile-nav.module.css +48 -27
  485. package/dist/shell/app-mobile-nav.module.css.d.ts +0 -1
  486. package/dist/shell/app-sidebar-account.d.ts +2 -1
  487. package/dist/shell/app-sidebar-account.d.ts.map +1 -1
  488. package/dist/shell/app-sidebar-account.js +57 -22
  489. package/dist/shell/app-sidebar.d.ts +10 -4
  490. package/dist/shell/app-sidebar.d.ts.map +1 -1
  491. package/dist/shell/app-sidebar.js +78 -103
  492. package/dist/shell/app-sidebar.module.css +63 -96
  493. package/dist/shell/app-sidebar.module.css.d.ts +0 -5
  494. package/dist/shell/index.d.ts +24 -10
  495. package/dist/shell/index.d.ts.map +1 -1
  496. package/dist/shell/index.js +60 -29
  497. package/dist/shell/isomorphic-layout-effect.d.ts +14 -0
  498. package/dist/shell/isomorphic-layout-effect.d.ts.map +1 -0
  499. package/dist/shell/isomorphic-layout-effect.js +5 -0
  500. package/dist/shell/mobile-nav-model.d.ts +1 -1
  501. package/dist/shell/mobile-nav-model.d.ts.map +1 -1
  502. package/dist/shell/mobile-nav-model.js +27 -6
  503. package/dist/shell/nav-count-badge.d.ts +5 -3
  504. package/dist/shell/nav-count-badge.d.ts.map +1 -1
  505. package/dist/shell/nav-count-badge.js +3 -1
  506. package/dist/{nav/types.d.ts → shell/nav-types.d.ts} +16 -7
  507. package/dist/shell/nav-types.d.ts.map +1 -0
  508. package/dist/shell/page-aside.d.ts +43 -0
  509. package/dist/shell/page-aside.d.ts.map +1 -0
  510. package/dist/shell/page-aside.js +175 -0
  511. package/dist/shell/page-aside.module.css +174 -0
  512. package/dist/shell/page-aside.module.css.d.ts +14 -0
  513. package/dist/shell/page-bar.d.ts +55 -15
  514. package/dist/shell/page-bar.d.ts.map +1 -1
  515. package/dist/shell/page-bar.js +130 -41
  516. package/dist/shell/page-bar.module.css +107 -13
  517. package/dist/shell/page-bar.module.css.d.ts +4 -1
  518. package/dist/shell/page-title.d.ts +14 -0
  519. package/dist/shell/page-title.d.ts.map +1 -0
  520. package/dist/shell/page-title.js +25 -0
  521. package/dist/shell/page-title.module.css +33 -0
  522. package/dist/shell/page-title.module.css.d.ts +11 -0
  523. package/dist/shell/sidebar-block-model.d.ts +1 -1
  524. package/dist/shell/sidebar-block-model.d.ts.map +1 -1
  525. package/dist/shell/sidebar-blocks.d.ts +1 -1
  526. package/dist/shell/sidebar-blocks.d.ts.map +1 -1
  527. package/dist/shell/sidebar-search.d.ts +4 -2
  528. package/dist/shell/sidebar-search.d.ts.map +1 -1
  529. package/dist/shell/sidebar-search.js +9 -4
  530. package/dist/shell/sidebar-search.module.css +1 -1
  531. package/dist/shell/use-breakpoint.d.ts +11 -0
  532. package/dist/shell/use-breakpoint.d.ts.map +1 -0
  533. package/dist/shell/use-breakpoint.js +33 -0
  534. package/dist/state/fields.d.ts +26 -22
  535. package/dist/state/fields.d.ts.map +1 -1
  536. package/dist/state/fields.js +19 -18
  537. package/dist/state/persisted-or-local.d.ts +9 -0
  538. package/dist/state/persisted-or-local.d.ts.map +1 -0
  539. package/dist/state/persisted-or-local.js +24 -0
  540. package/dist/state.d.ts +1 -1
  541. package/dist/state.d.ts.map +1 -1
  542. package/dist/state.js +2 -6
  543. package/dist/styles.css +36 -0
  544. package/dist/surfaces.d.ts +25 -47
  545. package/dist/surfaces.d.ts.map +1 -1
  546. package/dist/surfaces.js +72 -55
  547. package/dist/theme/ctl-theme.d.ts.map +1 -1
  548. package/dist/theme/index.d.ts.map +1 -1
  549. package/dist/theme/index.js +102 -17
  550. package/dist/theme/nav-link.module.css +37 -26
  551. package/dist/theme/segmented-control.module.css +22 -0
  552. package/dist/theme/segmented-control.module.css.d.ts +1 -0
  553. package/dist/theme/theme-toggle.d.ts +9 -0
  554. package/dist/theme/theme-toggle.d.ts.map +1 -0
  555. package/dist/{theme-toggle/index.js → theme/theme-toggle.js} +9 -3
  556. package/dist/theme-lab/boot.d.ts +66 -0
  557. package/dist/theme-lab/boot.d.ts.map +1 -0
  558. package/dist/theme-lab/boot.js +82 -0
  559. package/dist/theme-lab/index.d.ts +4 -43
  560. package/dist/theme-lab/index.d.ts.map +1 -1
  561. package/dist/theme-lab/index.js +9 -69
  562. package/dist/tokens/index.d.ts +43 -0
  563. package/dist/tokens/index.d.ts.map +1 -1
  564. package/dist/tokens/index.js +45 -6
  565. package/dist/tokens/palette.d.ts +57 -25
  566. package/dist/tokens/palette.d.ts.map +1 -1
  567. package/dist/tokens/palette.js +44 -15
  568. package/dist/tokens.css +5 -5
  569. package/llms.txt +11 -26
  570. package/package.json +54 -34
  571. package/src/agent/ai-sdk-transport.ts +11 -4
  572. package/src/agent/coalesce.ts +2 -1
  573. package/src/agent/merge.ts +2 -1
  574. package/src/agent/part-list.tsx +2 -0
  575. package/src/agent/stick-to-bottom.tsx +9 -11
  576. package/src/agent/transport.ts +15 -2
  577. package/src/agent/use-agent-thread-runs.ts +65 -15
  578. package/src/agent-chat/composer.tsx +124 -103
  579. package/src/agent-chat/index.ts +6 -4
  580. package/src/agent-chat/relative-time.ts +2 -1
  581. package/src/agent-chat/thread-detail-panel.tsx +10 -6
  582. package/src/agent-chat/thread-feed-row.tsx +117 -34
  583. package/src/agent-chat/thread-feed.tsx +59 -27
  584. package/src/agent-chat/thread-message.tsx +48 -13
  585. package/src/agent-chat/thread-outcome-card.tsx +9 -1
  586. package/src/agent-chat/thread-workspace.tsx +72 -33
  587. package/src/agent-chat/tool-chip.tsx +8 -2
  588. package/src/agent-chat/virtualize.ts +48 -0
  589. package/src/charts/hooks/useBandPlot.ts +26 -8
  590. package/src/charts/index.ts +46 -14
  591. package/src/charts/kinds/BandStrip.tsx +36 -14
  592. package/src/charts/kinds/Bars.tsx +68 -20
  593. package/src/charts/kinds/Donut.tsx +30 -3
  594. package/src/charts/kinds/DualPanel.tsx +60 -13
  595. package/src/charts/kinds/Heatmap.tsx +90 -33
  596. package/src/charts/kinds/MirroredBars.tsx +21 -3
  597. package/src/charts/kinds/MultiLine.tsx +61 -18
  598. package/src/charts/kinds/StackedArea.tsx +77 -6
  599. package/src/charts/kinds/ZonedLine.tsx +72 -35
  600. package/src/charts/layout/auto-margin.ts +134 -21
  601. package/src/charts/layout/log-ticks.ts +90 -0
  602. package/src/charts/primitives/Axes.tsx +82 -5
  603. package/src/charts/primitives/CartesianChart.tsx +194 -41
  604. package/src/charts/primitives/ChartCard.tsx +111 -27
  605. package/src/charts/primitives/ChartFrame.tsx +111 -26
  606. package/src/charts/primitives/ChartLegend.tsx +43 -13
  607. package/src/charts/primitives/ChartPending.tsx +194 -10
  608. package/src/charts/primitives/ChartTooltip.tsx +37 -5
  609. package/src/charts/primitives/Crosshair.tsx +6 -3
  610. package/src/charts/primitives/chart-frame-layout.ts +212 -0
  611. package/src/charts/primitives/chart-tier.tsx +37 -0
  612. package/src/charts/series.ts +77 -1
  613. package/src/charts/sparklines/BarSparkline.tsx +11 -3
  614. package/src/charts/sparklines/LineSparkline.tsx +18 -4
  615. package/src/charts/sparklines/index.ts +2 -2
  616. package/src/charts/utils/format.ts +19 -27
  617. package/src/charts/utils/ticks.ts +149 -4
  618. package/src/cli/audit-allows.ts +371 -0
  619. package/src/cli/check-theme.ts +197 -0
  620. package/src/cli/doctor.ts +331 -0
  621. package/src/cli/guard-hook.ts +115 -0
  622. package/src/cli/help.ts +101 -0
  623. package/src/cli/index.ts +269 -3434
  624. package/src/cli/init.ts +247 -0
  625. package/src/cli/sync.ts +324 -0
  626. package/src/cli/tokens-css.ts +252 -0
  627. package/src/commands/ShortcutsHelp.tsx +10 -3
  628. package/src/commands/define-commands.ts +2 -2
  629. package/src/commands/define-overlays.ts +216 -1
  630. package/src/commands/index.ts +22 -1
  631. package/src/commands/overlays-mount.tsx +63 -31
  632. package/src/commands/shell-bridge.ts +86 -0
  633. package/src/common/errors.ts +143 -0
  634. package/src/common/index.ts +23 -0
  635. package/src/common/is-dev.ts +4 -0
  636. package/src/common/props.ts +71 -0
  637. package/src/common/query-state-like.ts +64 -0
  638. package/src/common/refs.ts +58 -0
  639. package/src/common/scroll-parent.ts +42 -0
  640. package/src/common/validate.ts +94 -0
  641. package/src/content/article-layout.module.css +11 -4
  642. package/src/content/callout.tsx +13 -7
  643. package/src/content/guide.tsx +14 -4
  644. package/src/content/heading-anchor.tsx +14 -3
  645. package/src/content/index.ts +2 -0
  646. package/src/content/markdown.tsx +6 -8
  647. package/src/content/prose.module.css +9 -7
  648. package/src/content/reading-progress.tsx +40 -15
  649. package/src/content/slug.ts +4 -0
  650. package/src/content/toc.tsx +47 -10
  651. package/src/controls/actions.tsx +90 -10
  652. package/src/controls/compare-filter.tsx +20 -3
  653. package/src/controls/control-group.tsx +11 -4
  654. package/src/controls/controls.module.css +169 -186
  655. package/src/controls/controls.module.css.d.ts +9 -11
  656. package/src/controls/enum-filter.tsx +32 -16
  657. package/src/controls/filter-context.tsx +14 -6
  658. package/src/controls/filter-pill.tsx +6 -3
  659. package/src/controls/filter-set.tsx +32 -13
  660. package/src/controls/filter-sheet.tsx +44 -194
  661. package/src/controls/index.ts +7 -0
  662. package/src/controls/multi-select-filter.tsx +177 -27
  663. package/src/controls/number-filter.tsx +61 -23
  664. package/src/controls/panel-row.module.css +86 -0
  665. package/src/controls/panel-row.module.css.d.ts +13 -0
  666. package/src/controls/panel-row.tsx +392 -0
  667. package/src/controls/range-filter.tsx +76 -39
  668. package/src/controls/search-filter.tsx +30 -12
  669. package/src/controls/select-filter.tsx +11 -1
  670. package/src/controls/slider-control.tsx +159 -0
  671. package/src/controls/sync-button.tsx +13 -3
  672. package/src/controls/toggle-filter.tsx +36 -16
  673. package/src/controls/view-tabs.tsx +63 -11
  674. package/src/controls-dates/date-range-picker.tsx +8 -1
  675. package/src/dashboard/delta-badge.tsx +75 -4
  676. package/src/dashboard/empty-state.tsx +67 -24
  677. package/src/dashboard/index.ts +24 -3
  678. package/src/dashboard/query-state.tsx +142 -85
  679. package/src/{section → dashboard}/section.module.css +11 -0
  680. package/src/dashboard/section.tsx +287 -0
  681. package/src/dashboard/settings-section.tsx +88 -32
  682. package/src/dashboard/stat-card.module.css +46 -31
  683. package/src/dashboard/stat-card.module.css.d.ts +1 -0
  684. package/src/dashboard/stat-card.tsx +186 -128
  685. package/src/dashboard/stat-group.module.css +66 -0
  686. package/src/dashboard/stat-group.module.css.d.ts +8 -0
  687. package/src/dashboard/stat-group.tsx +74 -0
  688. package/src/dashboard/widget-grid.module.css +53 -0
  689. package/src/dashboard/widget-grid.module.css.d.ts +9 -0
  690. package/src/dashboard/widget-grid.tsx +127 -0
  691. package/src/{widget-header → dashboard}/widget-header.module.css +72 -7
  692. package/src/dashboard/widget-header.tsx +292 -0
  693. package/src/data/data-table.module.css +64 -0
  694. package/src/data/data-table.module.css.d.ts +11 -0
  695. package/src/data/data-table.tsx +921 -348
  696. package/src/data/query-branch.ts +53 -0
  697. package/src/data/table.ts +9 -23
  698. package/src/data/virtual-list.tsx +190 -56
  699. package/src/data/virtual.ts +8 -4
  700. package/src/dev-dock.tsx +159 -0
  701. package/src/format/date.ts +184 -0
  702. package/src/format/index.ts +69 -0
  703. package/src/format/measure.ts +31 -0
  704. package/src/format/number.ts +129 -0
  705. package/src/format/shared.ts +63 -0
  706. package/src/forms/FormErrorSummary.tsx +13 -6
  707. package/src/forms/create-form.ts +2 -2
  708. package/src/forms/field.ts +42 -13
  709. package/src/forms/form-layout.module.css +145 -0
  710. package/src/forms/form-layout.module.css.d.ts +20 -0
  711. package/src/forms/form-layout.tsx +305 -0
  712. package/src/forms/form-state.tsx +94 -0
  713. package/src/forms/index.ts +37 -7
  714. package/src/forms/use-field-array.ts +94 -0
  715. package/src/forms/use-form-draft.ts +145 -53
  716. package/src/forms/use-form-submit.ts +199 -0
  717. package/src/guard/index.ts +99 -70
  718. package/src/guard/types.ts +7 -10
  719. package/src/index.ts +92 -19
  720. package/src/notifications/bell.tsx +18 -4
  721. package/src/notifications/center.tsx +18 -5
  722. package/src/notifications/define-notifications.ts +64 -18
  723. package/src/notifications/index.ts +17 -8
  724. package/src/notifications/mount-guard.ts +39 -0
  725. package/src/notifications/notify.tsx +122 -3
  726. package/src/notifications/store.ts +7 -0
  727. package/src/{connectivity → provider}/connectivity-indicator.tsx +7 -2
  728. package/src/{connectivity → provider}/connectivity-provider.tsx +5 -2
  729. package/src/{connectivity/types.ts → provider/connectivity-types.ts} +5 -2
  730. package/src/provider/error-fallback.module.css +21 -0
  731. package/src/provider/error-fallback.module.css.d.ts +9 -0
  732. package/src/provider/index.tsx +116 -28
  733. package/src/provider/lab-theme.ts +2 -1
  734. package/src/{connectivity → provider}/use-connectivity.ts +4 -3
  735. package/src/query-client.ts +100 -0
  736. package/src/{query/devtools.tsx → query-devtools.tsx} +6 -4
  737. package/src/register.ts +20 -4
  738. package/src/router-tanstack/index.ts +4 -15
  739. package/src/router-tanstack/nav.ts +1 -1
  740. package/src/router-tanstack/search-store.ts +6 -14
  741. package/src/router-tanstack/use-nav.ts +19 -14
  742. package/src/shell/account-types.ts +5 -2
  743. package/src/shell/app-brand.module.css +109 -0
  744. package/src/shell/app-brand.module.css.d.ts +14 -0
  745. package/src/shell/app-brand.tsx +140 -0
  746. package/src/shell/app-breadcrumbs.tsx +20 -10
  747. package/src/shell/app-header.module.css +10 -5
  748. package/src/shell/app-main.module.css +118 -0
  749. package/src/shell/app-main.module.css.d.ts +11 -0
  750. package/src/shell/app-mobile-nav.module.css +48 -27
  751. package/src/shell/app-mobile-nav.module.css.d.ts +0 -1
  752. package/src/shell/app-mobile-nav.tsx +71 -12
  753. package/src/shell/app-sidebar-account.tsx +29 -6
  754. package/src/shell/app-sidebar.module.css +63 -96
  755. package/src/shell/app-sidebar.module.css.d.ts +0 -5
  756. package/src/shell/app-sidebar.tsx +61 -105
  757. package/src/shell/index.tsx +179 -93
  758. package/src/shell/isomorphic-layout-effect.ts +14 -0
  759. package/src/shell/mobile-nav-model.ts +67 -11
  760. package/src/shell/nav-count-badge.tsx +6 -1
  761. package/src/{nav/types.ts → shell/nav-types.ts} +15 -6
  762. package/src/shell/page-aside.module.css +174 -0
  763. package/src/shell/page-aside.module.css.d.ts +14 -0
  764. package/src/shell/page-aside.tsx +327 -0
  765. package/src/shell/page-bar.module.css +107 -13
  766. package/src/shell/page-bar.module.css.d.ts +4 -1
  767. package/src/shell/page-bar.tsx +294 -94
  768. package/src/shell/page-title.module.css +33 -0
  769. package/src/shell/page-title.module.css.d.ts +11 -0
  770. package/src/shell/page-title.tsx +57 -0
  771. package/src/shell/sidebar-block-model.ts +1 -1
  772. package/src/shell/sidebar-blocks.tsx +1 -1
  773. package/src/shell/sidebar-search.module.css +1 -1
  774. package/src/shell/sidebar-search.tsx +13 -4
  775. package/src/shell/use-breakpoint.ts +73 -0
  776. package/src/state/fields.ts +50 -53
  777. package/src/state/persisted-or-local.ts +50 -0
  778. package/src/state.ts +0 -9
  779. package/src/styles.css +36 -0
  780. package/src/surfaces.ts +72 -57
  781. package/src/theme/ctl-theme.tsx +10 -0
  782. package/src/theme/index.ts +136 -16
  783. package/src/theme/nav-link.module.css +37 -26
  784. package/src/theme/segmented-control.module.css +22 -0
  785. package/src/theme/segmented-control.module.css.d.ts +1 -0
  786. package/src/{theme-toggle/index.tsx → theme/theme-toggle.tsx} +11 -4
  787. package/src/theme-lab/boot.ts +140 -0
  788. package/src/theme-lab/index.tsx +21 -112
  789. package/src/tokens/index.ts +60 -6
  790. package/src/tokens/palette.ts +70 -30
  791. package/dist/agent/adapter.test.d.ts +0 -2
  792. package/dist/agent/adapter.test.d.ts.map +0 -1
  793. package/dist/agent/ai-sdk-transport.test.d.ts +0 -2
  794. package/dist/agent/ai-sdk-transport.test.d.ts.map +0 -1
  795. package/dist/agent/coalesce.test.d.ts +0 -2
  796. package/dist/agent/coalesce.test.d.ts.map +0 -1
  797. package/dist/agent/foreign.test.d.ts +0 -2
  798. package/dist/agent/foreign.test.d.ts.map +0 -1
  799. package/dist/agent/id.test.d.ts +0 -2
  800. package/dist/agent/id.test.d.ts.map +0 -1
  801. package/dist/agent/merge.test.d.ts +0 -2
  802. package/dist/agent/merge.test.d.ts.map +0 -1
  803. package/dist/agent/part-list.test.d.ts +0 -2
  804. package/dist/agent/part-list.test.d.ts.map +0 -1
  805. package/dist/agent/parts.test.d.ts +0 -2
  806. package/dist/agent/parts.test.d.ts.map +0 -1
  807. package/dist/agent/thread.test.d.ts +0 -2
  808. package/dist/agent/thread.test.d.ts.map +0 -1
  809. package/dist/agent/transport.test.d.ts +0 -2
  810. package/dist/agent/transport.test.d.ts.map +0 -1
  811. package/dist/agent/use-agent-stream.test.d.ts +0 -2
  812. package/dist/agent/use-agent-stream.test.d.ts.map +0 -1
  813. package/dist/agent/use-agent-thread-runs.foreign.test.d.ts +0 -2
  814. package/dist/agent/use-agent-thread-runs.foreign.test.d.ts.map +0 -1
  815. package/dist/agent/use-agent-thread-runs.resume.test.d.ts +0 -2
  816. package/dist/agent/use-agent-thread-runs.resume.test.d.ts.map +0 -1
  817. package/dist/agent/use-agent-thread-runs.test.d.ts +0 -2
  818. package/dist/agent/use-agent-thread-runs.test.d.ts.map +0 -1
  819. package/dist/agent/use-agent-thread-runs.wedge.test.d.ts +0 -2
  820. package/dist/agent/use-agent-thread-runs.wedge.test.d.ts.map +0 -1
  821. package/dist/agent-chat/composer.test.d.ts +0 -2
  822. package/dist/agent-chat/composer.test.d.ts.map +0 -1
  823. package/dist/agent-chat/relative-time.test.d.ts +0 -2
  824. package/dist/agent-chat/relative-time.test.d.ts.map +0 -1
  825. package/dist/agent-chat/thread-feed-row.test.d.ts +0 -2
  826. package/dist/agent-chat/thread-feed-row.test.d.ts.map +0 -1
  827. package/dist/agent-chat/thread-feed.test.d.ts +0 -2
  828. package/dist/agent-chat/thread-feed.test.d.ts.map +0 -1
  829. package/dist/agent-chat/thread-message.test.d.ts +0 -2
  830. package/dist/agent-chat/thread-message.test.d.ts.map +0 -1
  831. package/dist/agent-chat/thread-workspace.test.d.ts +0 -2
  832. package/dist/agent-chat/thread-workspace.test.d.ts.map +0 -1
  833. package/dist/agent-chat/tool-chip.test.d.ts +0 -2
  834. package/dist/agent-chat/tool-chip.test.d.ts.map +0 -1
  835. package/dist/agent-chat/virtualize.type-guard.test.d.ts +0 -2
  836. package/dist/agent-chat/virtualize.type-guard.test.d.ts.map +0 -1
  837. package/dist/charts/cursor/resolve.test.d.ts +0 -2
  838. package/dist/charts/cursor/resolve.test.d.ts.map +0 -1
  839. package/dist/charts/cursor/store.test.d.ts +0 -2
  840. package/dist/charts/cursor/store.test.d.ts.map +0 -1
  841. package/dist/charts/kinds/BandStrip.test.d.ts +0 -2
  842. package/dist/charts/kinds/BandStrip.test.d.ts.map +0 -1
  843. package/dist/charts/kinds/Bars.test.d.ts +0 -2
  844. package/dist/charts/kinds/Bars.test.d.ts.map +0 -1
  845. package/dist/charts/kinds/DualPanel.test.d.ts +0 -2
  846. package/dist/charts/kinds/DualPanel.test.d.ts.map +0 -1
  847. package/dist/charts/kinds/MirroredBars.test.d.ts +0 -2
  848. package/dist/charts/kinds/MirroredBars.test.d.ts.map +0 -1
  849. package/dist/charts/kinds/MultiLine.test.d.ts +0 -2
  850. package/dist/charts/kinds/MultiLine.test.d.ts.map +0 -1
  851. package/dist/charts/kinds/StackedArea.test.d.ts +0 -2
  852. package/dist/charts/kinds/StackedArea.test.d.ts.map +0 -1
  853. package/dist/charts/kinds/ZonedLine.test.d.ts +0 -2
  854. package/dist/charts/kinds/ZonedLine.test.d.ts.map +0 -1
  855. package/dist/charts/layout/auto-margin.test.d.ts +0 -2
  856. package/dist/charts/layout/auto-margin.test.d.ts.map +0 -1
  857. package/dist/charts/primitives/CartesianChart.test.d.ts +0 -2
  858. package/dist/charts/primitives/CartesianChart.test.d.ts.map +0 -1
  859. package/dist/charts/primitives/ChartCard.test.d.ts +0 -2
  860. package/dist/charts/primitives/ChartCard.test.d.ts.map +0 -1
  861. package/dist/charts/primitives/ChartFrame.test.d.ts +0 -2
  862. package/dist/charts/primitives/ChartFrame.test.d.ts.map +0 -1
  863. package/dist/charts/primitives/ChartLegend.test.d.ts +0 -2
  864. package/dist/charts/primitives/ChartLegend.test.d.ts.map +0 -1
  865. package/dist/charts/primitives/ChartTooltip.test.d.ts +0 -2
  866. package/dist/charts/primitives/ChartTooltip.test.d.ts.map +0 -1
  867. package/dist/charts/primitives/XZoneRects.test.d.ts +0 -2
  868. package/dist/charts/primitives/XZoneRects.test.d.ts.map +0 -1
  869. package/dist/charts/series.test.d.ts +0 -2
  870. package/dist/charts/series.test.d.ts.map +0 -1
  871. package/dist/charts/utils/domain.test.d.ts +0 -2
  872. package/dist/charts/utils/domain.test.d.ts.map +0 -1
  873. package/dist/charts/utils/measure-text.test.d.ts +0 -2
  874. package/dist/charts/utils/measure-text.test.d.ts.map +0 -1
  875. package/dist/cli/check-coverage.test.d.ts +0 -2
  876. package/dist/cli/check-coverage.test.d.ts.map +0 -1
  877. package/dist/cli/check-theme.test.d.ts +0 -2
  878. package/dist/cli/check-theme.test.d.ts.map +0 -1
  879. package/dist/cli/help.test.d.ts +0 -2
  880. package/dist/cli/help.test.d.ts.map +0 -1
  881. package/dist/cli/init-sync.test.d.ts +0 -2
  882. package/dist/cli/init-sync.test.d.ts.map +0 -1
  883. package/dist/cli/placement-engine.test.d.ts +0 -2
  884. package/dist/cli/placement-engine.test.d.ts.map +0 -1
  885. package/dist/cli/shipped-versions.test.d.ts +0 -2
  886. package/dist/cli/shipped-versions.test.d.ts.map +0 -1
  887. package/dist/cli/tarball-parity.test.d.ts +0 -2
  888. package/dist/cli/tarball-parity.test.d.ts.map +0 -1
  889. package/dist/cli/template-format.test.d.ts +0 -2
  890. package/dist/cli/template-format.test.d.ts.map +0 -1
  891. package/dist/cli/template-ledger.test.d.ts +0 -2
  892. package/dist/cli/template-ledger.test.d.ts.map +0 -1
  893. package/dist/cli/tokens-css.test.d.ts +0 -2
  894. package/dist/cli/tokens-css.test.d.ts.map +0 -1
  895. package/dist/cli/toolchain-wiring.test.d.ts +0 -2
  896. package/dist/cli/toolchain-wiring.test.d.ts.map +0 -1
  897. package/dist/cli/waiver-audit.test.d.ts +0 -2
  898. package/dist/cli/waiver-audit.test.d.ts.map +0 -1
  899. package/dist/connectivity/connectivity-indicator.d.ts +0 -11
  900. package/dist/connectivity/connectivity-indicator.d.ts.map +0 -1
  901. package/dist/connectivity/connectivity-provider.d.ts.map +0 -1
  902. package/dist/connectivity/index.d.ts +0 -13
  903. package/dist/connectivity/index.d.ts.map +0 -1
  904. package/dist/connectivity/index.js +0 -8
  905. package/dist/connectivity/types.d.ts.map +0 -1
  906. package/dist/connectivity/use-connectivity.d.ts +0 -3
  907. package/dist/connectivity/use-connectivity.d.ts.map +0 -1
  908. package/dist/content/article-actions.test.d.ts +0 -2
  909. package/dist/content/article-actions.test.d.ts.map +0 -1
  910. package/dist/content/article-model.test.d.ts +0 -2
  911. package/dist/content/article-model.test.d.ts.map +0 -1
  912. package/dist/content/block-split.test.d.ts +0 -2
  913. package/dist/content/block-split.test.d.ts.map +0 -1
  914. package/dist/content/heading-components.test.d.ts +0 -2
  915. package/dist/content/heading-components.test.d.ts.map +0 -1
  916. package/dist/content/markdown.test.d.ts +0 -2
  917. package/dist/content/markdown.test.d.ts.map +0 -1
  918. package/dist/content/prose.module.css.test.d.ts +0 -2
  919. package/dist/content/prose.module.css.test.d.ts.map +0 -1
  920. package/dist/content/sanitize.test.d.ts +0 -2
  921. package/dist/content/sanitize.test.d.ts.map +0 -1
  922. package/dist/content/slug.test.d.ts +0 -2
  923. package/dist/content/slug.test.d.ts.map +0 -1
  924. package/dist/controls/actions.test.d.ts +0 -2
  925. package/dist/controls/actions.test.d.ts.map +0 -1
  926. package/dist/controls/actions.type-guard.test.d.ts +0 -2
  927. package/dist/controls/actions.type-guard.test.d.ts.map +0 -1
  928. package/dist/controls/control-group.test.d.ts +0 -2
  929. package/dist/controls/control-group.test.d.ts.map +0 -1
  930. package/dist/controls/controls.router.test.d.ts +0 -2
  931. package/dist/controls/controls.router.test.d.ts.map +0 -1
  932. package/dist/controls/filter-set.test.d.ts +0 -2
  933. package/dist/controls/filter-set.test.d.ts.map +0 -1
  934. package/dist/controls/peer-boundary.test.d.ts +0 -2
  935. package/dist/controls/peer-boundary.test.d.ts.map +0 -1
  936. package/dist/controls/props-contract.test.d.ts +0 -2
  937. package/dist/controls/props-contract.test.d.ts.map +0 -1
  938. package/dist/controls/range-filter.type-guard.test.d.ts +0 -2
  939. package/dist/controls/range-filter.type-guard.test.d.ts.map +0 -1
  940. package/dist/controls/sync-button.test.d.ts +0 -2
  941. package/dist/controls/sync-button.test.d.ts.map +0 -1
  942. package/dist/dashboard/query-state.test.d.ts +0 -2
  943. package/dist/dashboard/query-state.test.d.ts.map +0 -1
  944. package/dist/dashboard/settings-section.test.d.ts +0 -2
  945. package/dist/dashboard/settings-section.test.d.ts.map +0 -1
  946. package/dist/dashboard/stat-card.test.d.ts +0 -2
  947. package/dist/dashboard/stat-card.test.d.ts.map +0 -1
  948. package/dist/data/data-table.test.d.ts +0 -2
  949. package/dist/data/data-table.test.d.ts.map +0 -1
  950. package/dist/data/index.d.ts +0 -38
  951. package/dist/data/index.d.ts.map +0 -1
  952. package/dist/data/index.js +0 -2
  953. package/dist/guard/check-source.test.d.ts +0 -2
  954. package/dist/guard/check-source.test.d.ts.map +0 -1
  955. package/dist/guard/grace.test.d.ts +0 -20
  956. package/dist/guard/grace.test.d.ts.map +0 -1
  957. package/dist/guard/guard-hook.test.d.ts +0 -2
  958. package/dist/guard/guard-hook.test.d.ts.map +0 -1
  959. package/dist/motion/index.d.ts.map +0 -1
  960. package/dist/nav/types.d.ts.map +0 -1
  961. package/dist/notifications/overlay.d.ts +0 -20
  962. package/dist/notifications/overlay.d.ts.map +0 -1
  963. package/dist/notifications/overlay.js +0 -12
  964. package/dist/provider/index.test.d.ts +0 -2
  965. package/dist/provider/index.test.d.ts.map +0 -1
  966. package/dist/provider/lab-theme.test.d.ts +0 -2
  967. package/dist/provider/lab-theme.test.d.ts.map +0 -1
  968. package/dist/query/devtools.d.ts.map +0 -1
  969. package/dist/query/error-message.d.ts +0 -41
  970. package/dist/query/error-message.d.ts.map +0 -1
  971. package/dist/query/error-message.js +0 -30
  972. package/dist/query/error-message.test.d.ts +0 -2
  973. package/dist/query/error-message.test.d.ts.map +0 -1
  974. package/dist/query/index.d.ts +0 -47
  975. package/dist/query/index.d.ts.map +0 -1
  976. package/dist/query/index.js +0 -56
  977. package/dist/router-tanstack/field.d.ts +0 -14
  978. package/dist/router-tanstack/field.d.ts.map +0 -1
  979. package/dist/router-tanstack/field.js +0 -4
  980. package/dist/router-tanstack/multi-search-param-store.d.ts +0 -43
  981. package/dist/router-tanstack/multi-search-param-store.d.ts.map +0 -1
  982. package/dist/router-tanstack/multi-search-param-store.js +0 -30
  983. package/dist/router-tanstack/multi-search-param-store.test.d.ts +0 -2
  984. package/dist/router-tanstack/multi-search-param-store.test.d.ts.map +0 -1
  985. package/dist/router-tanstack/nav.test.d.ts +0 -2
  986. package/dist/router-tanstack/nav.test.d.ts.map +0 -1
  987. package/dist/router-tanstack/search-param-store.d.ts +0 -42
  988. package/dist/router-tanstack/search-param-store.d.ts.map +0 -1
  989. package/dist/router-tanstack/search-param-store.js +0 -25
  990. package/dist/router-tanstack/search-param-store.test.d.ts +0 -2
  991. package/dist/router-tanstack/search-param-store.test.d.ts.map +0 -1
  992. package/dist/router-tanstack/search-store.router.test.d.ts +0 -2
  993. package/dist/router-tanstack/search-store.router.test.d.ts.map +0 -1
  994. package/dist/router-tanstack/search-store.test.d.ts +0 -2
  995. package/dist/router-tanstack/search-store.test.d.ts.map +0 -1
  996. package/dist/router-tanstack/use-nav.test.d.ts +0 -2
  997. package/dist/router-tanstack/use-nav.test.d.ts.map +0 -1
  998. package/dist/section/index.d.ts +0 -2
  999. package/dist/section/index.d.ts.map +0 -1
  1000. package/dist/section/index.js +0 -4
  1001. package/dist/section/section.d.ts +0 -24
  1002. package/dist/section/section.d.ts.map +0 -1
  1003. package/dist/section/section.js +0 -126
  1004. package/dist/section/section.test.d.ts +0 -2
  1005. package/dist/section/section.test.d.ts.map +0 -1
  1006. package/dist/shell/app-mobile-nav.test.d.ts +0 -2
  1007. package/dist/shell/app-mobile-nav.test.d.ts.map +0 -1
  1008. package/dist/shell/app-sidebar.test.d.ts +0 -2
  1009. package/dist/shell/app-sidebar.test.d.ts.map +0 -1
  1010. package/dist/shell/index.test.d.ts +0 -2
  1011. package/dist/shell/index.test.d.ts.map +0 -1
  1012. package/dist/shell/mobile-nav-model.test.d.ts +0 -2
  1013. package/dist/shell/mobile-nav-model.test.d.ts.map +0 -1
  1014. package/dist/shell/page-bar.test.d.ts +0 -2
  1015. package/dist/shell/page-bar.test.d.ts.map +0 -1
  1016. package/dist/state/fields.test.d.ts +0 -2
  1017. package/dist/state/fields.test.d.ts.map +0 -1
  1018. package/dist/state/persisted.test.d.ts +0 -2
  1019. package/dist/state/persisted.test.d.ts.map +0 -1
  1020. package/dist/styles.floor.test.d.ts +0 -2
  1021. package/dist/styles.floor.test.d.ts.map +0 -1
  1022. package/dist/theme/border-coverage.test.d.ts +0 -18
  1023. package/dist/theme/border-coverage.test.d.ts.map +0 -1
  1024. package/dist/theme/contrast.test.d.ts +0 -2
  1025. package/dist/theme/contrast.test.d.ts.map +0 -1
  1026. package/dist/theme/ctl-theme.test.d.ts +0 -2
  1027. package/dist/theme/ctl-theme.test.d.ts.map +0 -1
  1028. package/dist/theme/ctl-tier-coverage.test.d.ts +0 -2
  1029. package/dist/theme/ctl-tier-coverage.test.d.ts.map +0 -1
  1030. package/dist/theme/density-option.test.d.ts +0 -2
  1031. package/dist/theme/density-option.test.d.ts.map +0 -1
  1032. package/dist/theme/density-relations.test.d.ts +0 -2
  1033. package/dist/theme/density-relations.test.d.ts.map +0 -1
  1034. package/dist/theme/derive-theme.test.d.ts +0 -2
  1035. package/dist/theme/derive-theme.test.d.ts.map +0 -1
  1036. package/dist/theme/divider-law.test.d.ts +0 -2
  1037. package/dist/theme/divider-law.test.d.ts.map +0 -1
  1038. package/dist/theme/fonts-option.test.d.ts +0 -2
  1039. package/dist/theme/fonts-option.test.d.ts.map +0 -1
  1040. package/dist/theme/icon-slot.test.d.ts +0 -2
  1041. package/dist/theme/icon-slot.test.d.ts.map +0 -1
  1042. package/dist/theme/layout-rhythm-css.test.d.ts +0 -2
  1043. package/dist/theme/layout-rhythm-css.test.d.ts.map +0 -1
  1044. package/dist/theme/radius-option.test.d.ts +0 -2
  1045. package/dist/theme/radius-option.test.d.ts.map +0 -1
  1046. package/dist/theme/radius.test.d.ts +0 -2
  1047. package/dist/theme/radius.test.d.ts.map +0 -1
  1048. package/dist/theme/shadow-surfaces.test.d.ts +0 -26
  1049. package/dist/theme/shadow-surfaces.test.d.ts.map +0 -1
  1050. package/dist/theme/spacing.test.d.ts +0 -2
  1051. package/dist/theme/spacing.test.d.ts.map +0 -1
  1052. package/dist/theme/use-basalt-spacing.test.d.ts +0 -2
  1053. package/dist/theme/use-basalt-spacing.test.d.ts.map +0 -1
  1054. package/dist/theme-lab/derive-controls.test.d.ts +0 -2
  1055. package/dist/theme-lab/derive-controls.test.d.ts.map +0 -1
  1056. package/dist/theme-lab/derive-state.test.d.ts +0 -2
  1057. package/dist/theme-lab/derive-state.test.d.ts.map +0 -1
  1058. package/dist/theme-lab/theme-lab.test.d.ts +0 -2
  1059. package/dist/theme-lab/theme-lab.test.d.ts.map +0 -1
  1060. package/dist/theme-toggle/index.d.ts +0 -8
  1061. package/dist/theme-toggle/index.d.ts.map +0 -1
  1062. package/dist/tokens/build-fonts-css.test.d.ts +0 -2
  1063. package/dist/tokens/build-fonts-css.test.d.ts.map +0 -1
  1064. package/dist/tokens/build-radius-css.test.d.ts +0 -2
  1065. package/dist/tokens/build-radius-css.test.d.ts.map +0 -1
  1066. package/dist/tokens/chart-margin.test.d.ts +0 -2
  1067. package/dist/tokens/chart-margin.test.d.ts.map +0 -1
  1068. package/dist/tokens/density.test.d.ts +0 -2
  1069. package/dist/tokens/density.test.d.ts.map +0 -1
  1070. package/dist/tokens/derive-radius.test.d.ts +0 -2
  1071. package/dist/tokens/derive-radius.test.d.ts.map +0 -1
  1072. package/dist/tokens/derive.test.d.ts +0 -2
  1073. package/dist/tokens/derive.test.d.ts.map +0 -1
  1074. package/dist/tokens/palette.test.d.ts +0 -2
  1075. package/dist/tokens/palette.test.d.ts.map +0 -1
  1076. package/dist/tokens/text-scale.test.d.ts +0 -2
  1077. package/dist/tokens/text-scale.test.d.ts.map +0 -1
  1078. package/dist/vite-color-mix.test.d.ts +0 -2
  1079. package/dist/vite-color-mix.test.d.ts.map +0 -1
  1080. package/dist/vite.test.d.ts +0 -2
  1081. package/dist/vite.test.d.ts.map +0 -1
  1082. package/dist/widget-header/delta-badge.d.ts +0 -13
  1083. package/dist/widget-header/delta-badge.d.ts.map +0 -1
  1084. package/dist/widget-header/delta-badge.js +0 -29
  1085. package/dist/widget-header/delta-badge.test.d.ts +0 -2
  1086. package/dist/widget-header/delta-badge.test.d.ts.map +0 -1
  1087. package/dist/widget-header/index.d.ts +0 -3
  1088. package/dist/widget-header/index.d.ts.map +0 -1
  1089. package/dist/widget-header/index.js +0 -6
  1090. package/dist/widget-header/no-mantine.test.d.ts +0 -2
  1091. package/dist/widget-header/no-mantine.test.d.ts.map +0 -1
  1092. package/dist/widget-header/widget-header.d.ts +0 -67
  1093. package/dist/widget-header/widget-header.d.ts.map +0 -1
  1094. package/dist/widget-header/widget-header.test.d.ts +0 -2
  1095. package/dist/widget-header/widget-header.test.d.ts.map +0 -1
  1096. package/src/agent/adapter.test.ts +0 -1640
  1097. package/src/agent/ai-sdk-transport.test.ts +0 -658
  1098. package/src/agent/coalesce.test.ts +0 -387
  1099. package/src/agent/foreign.test.ts +0 -51
  1100. package/src/agent/id.test.ts +0 -169
  1101. package/src/agent/merge.test.ts +0 -206
  1102. package/src/agent/part-list.test.tsx +0 -112
  1103. package/src/agent/parts.test.ts +0 -720
  1104. package/src/agent/thread.test.ts +0 -220
  1105. package/src/agent/transport.test.ts +0 -70
  1106. package/src/agent/use-agent-stream.test.tsx +0 -287
  1107. package/src/agent/use-agent-thread-runs.foreign.test.tsx +0 -138
  1108. package/src/agent/use-agent-thread-runs.resume.test.tsx +0 -294
  1109. package/src/agent/use-agent-thread-runs.test.tsx +0 -1120
  1110. package/src/agent/use-agent-thread-runs.wedge.test.tsx +0 -387
  1111. package/src/agent-chat/composer.test.tsx +0 -924
  1112. package/src/agent-chat/relative-time.test.ts +0 -95
  1113. package/src/agent-chat/thread-feed-row.test.tsx +0 -510
  1114. package/src/agent-chat/thread-feed.test.tsx +0 -241
  1115. package/src/agent-chat/thread-message.test.tsx +0 -1285
  1116. package/src/agent-chat/thread-workspace.test.tsx +0 -169
  1117. package/src/agent-chat/tool-chip.test.tsx +0 -139
  1118. package/src/agent-chat/virtualize.type-guard.test.ts +0 -49
  1119. package/src/charts/cursor/resolve.test.ts +0 -151
  1120. package/src/charts/cursor/store.test.ts +0 -64
  1121. package/src/charts/kinds/BandStrip.test.tsx +0 -282
  1122. package/src/charts/kinds/Bars.test.tsx +0 -183
  1123. package/src/charts/kinds/DualPanel.test.tsx +0 -527
  1124. package/src/charts/kinds/MirroredBars.test.tsx +0 -232
  1125. package/src/charts/kinds/MultiLine.test.tsx +0 -218
  1126. package/src/charts/kinds/StackedArea.test.tsx +0 -114
  1127. package/src/charts/kinds/ZonedLine.test.tsx +0 -147
  1128. package/src/charts/layout/auto-margin.test.ts +0 -42
  1129. package/src/charts/primitives/CartesianChart.test.tsx +0 -647
  1130. package/src/charts/primitives/ChartCard.test.tsx +0 -66
  1131. package/src/charts/primitives/ChartFrame.test.tsx +0 -142
  1132. package/src/charts/primitives/ChartLegend.test.tsx +0 -78
  1133. package/src/charts/primitives/ChartTooltip.test.tsx +0 -44
  1134. package/src/charts/primitives/XZoneRects.test.tsx +0 -123
  1135. package/src/charts/series.test.ts +0 -112
  1136. package/src/charts/utils/domain.test.ts +0 -54
  1137. package/src/charts/utils/measure-text.test.ts +0 -36
  1138. package/src/cli/check-coverage.test.ts +0 -297
  1139. package/src/cli/check-theme.test.ts +0 -837
  1140. package/src/cli/help.test.ts +0 -170
  1141. package/src/cli/init-sync.test.ts +0 -343
  1142. package/src/cli/placement-engine.test.ts +0 -298
  1143. package/src/cli/shipped-versions.test.ts +0 -83
  1144. package/src/cli/tarball-parity.test.ts +0 -44
  1145. package/src/cli/template-format.test.ts +0 -64
  1146. package/src/cli/template-ledger.test.ts +0 -219
  1147. package/src/cli/tokens-css.test.ts +0 -249
  1148. package/src/cli/toolchain-wiring.test.ts +0 -1358
  1149. package/src/cli/waiver-audit.test.ts +0 -215
  1150. package/src/connectivity/index.ts +0 -18
  1151. package/src/content/article-actions.test.ts +0 -78
  1152. package/src/content/article-model.test.ts +0 -119
  1153. package/src/content/block-split.test.ts +0 -75
  1154. package/src/content/heading-components.test.tsx +0 -65
  1155. package/src/content/markdown.test.tsx +0 -603
  1156. package/src/content/prose.module.css.test.ts +0 -39
  1157. package/src/content/sanitize.test.ts +0 -659
  1158. package/src/content/slug.test.ts +0 -62
  1159. package/src/controls/actions.test.tsx +0 -252
  1160. package/src/controls/actions.type-guard.test.ts +0 -63
  1161. package/src/controls/control-group.test.tsx +0 -229
  1162. package/src/controls/controls.router.test.tsx +0 -1053
  1163. package/src/controls/filter-set.test.tsx +0 -472
  1164. package/src/controls/peer-boundary.test.ts +0 -85
  1165. package/src/controls/props-contract.test.tsx +0 -137
  1166. package/src/controls/range-filter.type-guard.test.tsx +0 -122
  1167. package/src/controls/sync-button.test.tsx +0 -183
  1168. package/src/dashboard/query-state.test.tsx +0 -152
  1169. package/src/dashboard/settings-section.test.tsx +0 -56
  1170. package/src/dashboard/stat-card.test.tsx +0 -385
  1171. package/src/data/data-table.test.tsx +0 -434
  1172. package/src/data/index.ts +0 -41
  1173. package/src/guard/check-source.test.ts +0 -3388
  1174. package/src/guard/grace.test.ts +0 -158
  1175. package/src/guard/guard-hook.test.ts +0 -203
  1176. package/src/notifications/overlay.tsx +0 -64
  1177. package/src/provider/index.test.tsx +0 -101
  1178. package/src/provider/lab-theme.test.ts +0 -147
  1179. package/src/query/error-message.test.ts +0 -67
  1180. package/src/query/error-message.ts +0 -70
  1181. package/src/query/index.ts +0 -97
  1182. package/src/router-tanstack/field.ts +0 -35
  1183. package/src/router-tanstack/multi-search-param-store.test.ts +0 -124
  1184. package/src/router-tanstack/multi-search-param-store.ts +0 -106
  1185. package/src/router-tanstack/nav.test.ts +0 -111
  1186. package/src/router-tanstack/search-param-store.test.ts +0 -135
  1187. package/src/router-tanstack/search-param-store.ts +0 -100
  1188. package/src/router-tanstack/search-store.router.test.tsx +0 -882
  1189. package/src/router-tanstack/search-store.test.ts +0 -578
  1190. package/src/router-tanstack/use-nav.test.tsx +0 -187
  1191. package/src/section/index.ts +0 -1
  1192. package/src/section/section.test.tsx +0 -204
  1193. package/src/section/section.tsx +0 -220
  1194. package/src/shell/app-mobile-nav.test.tsx +0 -403
  1195. package/src/shell/app-sidebar.test.tsx +0 -509
  1196. package/src/shell/index.test.tsx +0 -428
  1197. package/src/shell/mobile-nav-model.test.ts +0 -517
  1198. package/src/shell/page-bar.test.tsx +0 -316
  1199. package/src/state/fields.test.tsx +0 -512
  1200. package/src/state/persisted.test.ts +0 -91
  1201. package/src/styles.floor.test.ts +0 -36
  1202. package/src/theme/border-coverage.test.ts +0 -272
  1203. package/src/theme/contrast.test.ts +0 -354
  1204. package/src/theme/ctl-theme.test.tsx +0 -275
  1205. package/src/theme/ctl-tier-coverage.test.ts +0 -170
  1206. package/src/theme/density-option.test.ts +0 -96
  1207. package/src/theme/density-relations.test.ts +0 -506
  1208. package/src/theme/derive-theme.test.ts +0 -101
  1209. package/src/theme/divider-law.test.ts +0 -259
  1210. package/src/theme/fonts-option.test.ts +0 -75
  1211. package/src/theme/icon-slot.test.tsx +0 -275
  1212. package/src/theme/layout-rhythm-css.test.ts +0 -72
  1213. package/src/theme/radius-option.test.ts +0 -86
  1214. package/src/theme/radius.test.ts +0 -142
  1215. package/src/theme/shadow-surfaces.test.ts +0 -488
  1216. package/src/theme/spacing.test.ts +0 -495
  1217. package/src/theme/use-basalt-spacing.test.tsx +0 -55
  1218. package/src/theme-lab/derive-controls.test.ts +0 -94
  1219. package/src/theme-lab/derive-state.test.ts +0 -71
  1220. package/src/theme-lab/theme-lab.test.ts +0 -46
  1221. package/src/tokens/build-fonts-css.test.ts +0 -52
  1222. package/src/tokens/build-radius-css.test.ts +0 -25
  1223. package/src/tokens/chart-margin.test.ts +0 -39
  1224. package/src/tokens/density.test.ts +0 -259
  1225. package/src/tokens/derive-radius.test.ts +0 -62
  1226. package/src/tokens/derive.test.ts +0 -30
  1227. package/src/tokens/palette.test.ts +0 -114
  1228. package/src/tokens/text-scale.test.ts +0 -51
  1229. package/src/vite-color-mix.test.ts +0 -46
  1230. package/src/vite.test.ts +0 -423
  1231. package/src/widget-header/delta-badge.test.tsx +0 -60
  1232. package/src/widget-header/delta-badge.tsx +0 -57
  1233. package/src/widget-header/index.ts +0 -2
  1234. package/src/widget-header/no-mantine.test.ts +0 -33
  1235. package/src/widget-header/widget-header.test.tsx +0 -187
  1236. package/src/widget-header/widget-header.tsx +0 -213
  1237. /package/dist/{motion/index.js → common/motion.js} +0 -0
  1238. /package/dist/{section → dashboard}/section.module.css.d.ts +0 -0
  1239. /package/dist/{widget-header → dashboard}/widget-header.module.css.d.ts +0 -0
  1240. /package/dist/{connectivity/types.js → provider/connectivity-types.js} +0 -0
  1241. /package/dist/{connectivity → provider}/use-connectivity.js +0 -0
  1242. /package/dist/{nav/types.js → shell/nav-types.js} +0 -0
  1243. /package/src/{motion/index.ts → common/motion.ts} +0 -0
  1244. /package/src/{section → dashboard}/section.module.css.d.ts +0 -0
  1245. /package/src/{widget-header → dashboard}/widget-header.module.css.d.ts +0 -0
@@ -0,0 +1,94 @@
1
+ /**
2
+ * ./forms — useFieldArray: the list-field surface over Mantine's four list actions.
3
+ * Mantine-coupled. Optional peer: @mantine/form.
4
+ *
5
+ * The gap (audit B §4): `insertListItem` / `removeListItem` / `reorderListItem` are all reachable
6
+ * off the raw form object, but they are unexported by name, undocumented in the forms doctrine, and
7
+ * each takes a different argument shape (`(path, item, index?)`, `(path, index)`,
8
+ * `(path, { from, to })`). The list ALSO has to be read back out of the values by dotted path, and
9
+ * every row needs `form.key(\`${path}.${i}\`)` or the uncontrolled reconciler reuses the wrong DOM
10
+ * node when a row is removed from the middle — which is the defect this hook exists to make
11
+ * unwritable.
12
+ */
13
+ import type { FormArrayElement, LooseKeys, UseFormReturnType } from '@mantine/form'
14
+
15
+ export type UseFieldArrayReturn<Item> = {
16
+ /** The live list. `[]` when the path holds nothing, so a call site never guards before mapping. */
17
+ items: Item[]
18
+ /** Push one item onto the end. */
19
+ append: (value: Item) => void
20
+ /** Drop the item at `index`. Mantine re-indexes the field errors with it. */
21
+ remove: (index: number) => void
22
+ /** Move one item, e.g. from a drag handle or a pair of arrow buttons. */
23
+ move: (from: number, to: number) => void
24
+ /**
25
+ * Mantine's reconciler key for row `index` (`form.key('<path>.<index>')`) — pass it as the row's
26
+ * JSX `key`, never spread it.
27
+ *
28
+ * **Positional, and that is a real limit worth stating**: it identifies the SLOT, not the item.
29
+ * Mantine's list actions write values through `$values` directly and never bump the form-level
30
+ * key generation (verified in 9.3.2's use-form-list), so removing row 0 does not change row 0's
31
+ * key — it changes which item sits there. That is correct for an append/remove list, where the
32
+ * uncontrolled inputs below re-read their `defaultValue` from the new values anyway. A list the
33
+ * USER reorders wants an identity key instead: put a `randomId()` on the item and key the row on
34
+ * that.
35
+ */
36
+ key: (index: number) => string
37
+ }
38
+
39
+ /**
40
+ * Reads and edits a list field as one object.
41
+ *
42
+ * **`items` is read from `form.getValues()`, not from `form.values`**, so it is correct under the
43
+ * `mode: 'uncontrolled'` default `useBasaltForm` sets: the list actions all re-render the form
44
+ * (they call `setValues` with `updateState: true`), so the snapshot this returns is the one the
45
+ * caller just produced.
46
+ *
47
+ * @example
48
+ * const items = useFieldArray(form, 'contacts')
49
+ *
50
+ * {items.items.map((_, index) => (
51
+ * <FormRow key={items.key(index)} label={`Contact ${index + 1}`}>
52
+ * <TextInput
53
+ * key={fieldKey(form, `contacts.${index}.email`)}
54
+ * {...inputProps(form, `contacts.${index}.email`)}
55
+ * />
56
+ * <Button onClick={() => items.remove(index)}>Remove</Button>
57
+ * </FormRow>
58
+ * ))}
59
+ * <Button onClick={() => items.append({ email: '' })}>Add contact</Button>
60
+ */
61
+ export function useFieldArray<
62
+ Values extends Record<string, unknown>,
63
+ Path extends LooseKeys<Values>,
64
+ >(
65
+ form: UseFormReturnType<Values>,
66
+ path: Path,
67
+ ): UseFieldArrayReturn<FormArrayElement<Values, Path & string>> {
68
+ type Item = FormArrayElement<Values, Path & string>
69
+
70
+ return {
71
+ items: readList<Item>(form.getValues(), String(path)),
72
+ append: (value) => form.insertListItem(path, value),
73
+ remove: (index) => form.removeListItem(path, index),
74
+ move: (from, to) => form.reorderListItem(path, { from, to }),
75
+ key: (index) => form.key(`${String(path)}.${index}`),
76
+ }
77
+ }
78
+
79
+ /**
80
+ * The dotted-path read. Mantine's own `getPath` is internal to `@mantine/form/paths` and is not on
81
+ * the package's public entry, so this walks the path itself rather than reaching past the export
82
+ * map for six lines.
83
+ *
84
+ * Returns `[]` for a missing path or a non-array value: the alternative is a `.map` on `undefined`
85
+ * at the call site, and "the field is not a list" is a typing error the compiler already reports.
86
+ */
87
+ function readList<Item>(values: Record<string, unknown>, path: string): Item[] {
88
+ let current: unknown = values
89
+ for (const segment of path.split('.')) {
90
+ if (current === null || typeof current !== 'object') return []
91
+ current = (current as Record<string, unknown>)[segment]
92
+ }
93
+ return Array.isArray(current) ? (current as Item[]) : []
94
+ }
@@ -2,28 +2,21 @@
2
2
  * ./forms — useFormDraft: autosave/restore/clear draft persistence via createPersistedState.
3
3
  * Mantine-coupled (reads from UseFormReturnType). Optional peer: @mantine/form.
4
4
  *
5
- * AUTOSAVE NOTE: @mantine/form v9 has no whole-form subscription hook on an existing form
6
- * instance — `form.watch` is per-path only. The cleanest autosave path is to thread
7
- * `onValuesChange` through useBasaltForm at creation time (the consumer passes the callback
8
- * there). useFormDraft therefore exposes an explicit `saveDraft()` that the consumer calls
9
- * at field blur / form change events. Wire it via useBasaltForm's `onValuesChange` prop for
10
- * fully-automatic autosave:
5
+ * AUTOSAVE: `autosave: true` and the hook owns its own subscription. It used to be a documented
6
+ * ref dance — declare a `saveDraftRef`, pass `onValuesChange: () => saveDraftRef.current?.()` into
7
+ * `useBasaltForm`, assign the ref after the hook returns — which was copied verbatim into the
8
+ * playground, and a five-line init-order puzzle a consumer has to re-derive is a hook that has not
9
+ * finished being written. The dance still works; it is no longer the recommended path.
11
10
  *
12
- * @example (manual blur-based autosave)
11
+ * @example (automatic)
13
12
  * const form = useBasaltForm({ initialValues, schema })
14
- * const { clearDraft, saveDraft } = useFormDraft(form, { key: 'my-form', version: 1 })
15
- * <TextInput {...field(form, 'name')} onBlur={saveDraft} />
13
+ * const { clearDraft, hasDraft } = useFormDraft(form, { key: 'my-form', version: 1, autosave: true })
16
14
  *
17
- * @example (automatic via onValuesChange in useBasaltForm — use saveDraft ref pattern)
18
- * const saveDraftRef = useRef<(() => void) | null>(null)
19
- * const form = useBasaltForm({ initialValues, schema, onValuesChange: () => saveDraftRef.current?.() })
15
+ * @example (manual — a blur-only save, or a form not created by useBasaltForm)
20
16
  * const { clearDraft, saveDraft } = useFormDraft(form, { key: 'my-form', version: 1 })
21
- * saveDraftRef.current = saveDraft
22
- * // NOTE: the ref pattern avoids the init-order problem — form is created first, the ref
23
- * // is populated after useFormDraft runs (hooks run top-to-bottom), so by the time
24
- * // onValuesChange fires on user interaction the ref is always populated.
17
+ * <TextInput key={fieldKey(form, 'name')} {...inputProps(form, 'name')} onBlur={saveDraft} />
25
18
  */
26
- import { useEffect, useRef } from 'react'
19
+ import { useCallback, useEffect, useRef } from 'react'
27
20
  import type { UseFormReturnType } from '@mantine/form'
28
21
  import { createPersistedState } from '../state'
29
22
  import type { StandardSchemaV1 } from '../register'
@@ -42,8 +35,26 @@ export type UseFormDraftOptions<Values> = {
42
35
  version: number
43
36
  /** Optional Standard Schema to validate the persisted draft before restoring. */
44
37
  schema?: StandardSchemaV1<unknown, Values>
38
+ /**
39
+ * Persist on every value change, debounced. `true` uses {@link DEFAULT_AUTOSAVE_DEBOUNCE_MS};
40
+ * pass `{ debounceMs }` to tune it (`0` saves on the next macrotask).
41
+ *
42
+ * **The on/off decision and the watched key set are read ONCE, on mount.** The subscription is
43
+ * `form.watch` per top-level key, and `watch` calls `useEffect` internally, so both are a hook
44
+ * count and neither may move between renders. Flipping this prop later therefore neither starts
45
+ * nor stops autosaving; a form whose top-level SHAPE changes after mount needs `saveDraft` called
46
+ * by hand for the new keys. `debounceMs` is the exception — it is read at FIRE time, so a form
47
+ * that widens its window mid-edit gets the new one.
48
+ *
49
+ * Nested edits are covered: Mantine notifies a parent-path subscriber for a `a.b.c` change, so
50
+ * watching the top level watches the whole tree.
51
+ */
52
+ autosave?: boolean | { debounceMs?: number }
45
53
  }
46
54
 
55
+ /** Long enough that a typed word is one write, short enough that a closed tab keeps the sentence. */
56
+ export const DEFAULT_AUTOSAVE_DEBOUNCE_MS = 500
57
+
47
58
  /** Return value of useFormDraft. */
48
59
  export type UseFormDraftReturn = {
49
60
  /** True when a draft different from the initial values is persisted. */
@@ -63,15 +74,13 @@ export type UseFormDraftReturn = {
63
74
  * MUST-HAVES:
64
75
  * - Restores the draft once on mount if a draft is persisted.
65
76
  * - `clearDraft()` removes the persisted draft (call in onSubmit success).
66
- * - `saveDraft()` snapshots current form values (call onBlur or wire into useBasaltForm's `onValuesChange`).
67
- *
68
- * AUTOSAVE: @mantine/form has no whole-form change subscription on an existing form.
69
- * The cleanest path is to pass `saveDraft` to `useBasaltForm({ onValuesChange: () => saveDraft() })`.
70
- * For forms not created via useBasaltForm, call `saveDraft` manually on blur.
77
+ * - `saveDraft()` snapshots current form values (call onBlur, or leave it to `autosave`).
78
+ * - `autosave: true` subscribes for you — see {@link UseFormDraftOptions.autosave} for the two
79
+ * properties that are frozen at mount, and why.
71
80
  *
72
81
  * @example
73
82
  * import * as v from 'valibot'
74
- * import { useBasaltForm, field, FormErrorSummary, useFormDraft } from 'basalt-ui/forms'
83
+ * import { useBasaltForm, inputProps, fieldKey, FormErrorSummary, useFormDraft } from 'basalt-ui/forms'
75
84
  *
76
85
  * const Schema = v.object({ name: v.pipe(v.string(), v.minLength(2)), amount: v.number() })
77
86
  * type Values = v.InferOutput<typeof Schema>
@@ -79,13 +88,11 @@ export type UseFormDraftReturn = {
79
88
  *
80
89
  * function MyForm() {
81
90
  * const form = useBasaltForm({ initialValues: INITIAL, schema: Schema, mode: 'uncontrolled' })
82
- * const { clearDraft, saveDraft, hasDraft } = useFormDraft(form, { key: 'my-form', version: 1 })
83
- * // Wire saveDraft into onValuesChange after form creation via a ref or external callback:
84
- * // form is created above; wire via onBlur as the safe fallback shown here.
91
+ * const { clearDraft, hasDraft } = useFormDraft(form, { key: 'my-form', version: 1, autosave: true })
85
92
  * return (
86
93
  * <form onSubmit={form.onSubmit((values) => { submit(values); clearDraft() })}>
87
94
  * <FormErrorSummary form={form} />
88
- * <TextInput {...field(form, 'name')} onBlur={saveDraft} />
95
+ * <TextInput key={fieldKey(form, 'name')} {...inputProps(form, 'name')} />
89
96
  * {hasDraft && <Button onClick={clearDraft}>Clear draft</Button>}
90
97
  * </form>
91
98
  * )
@@ -95,40 +102,21 @@ export function useFormDraft<Values extends Record<string, unknown>>(
95
102
  form: UseFormReturnType<Values>,
96
103
  opts: UseFormDraftOptions<Values>,
97
104
  ): UseFormDraftReturn {
98
- const { key, version, schema } = opts
105
+ const { key, version, schema, autosave } = opts
99
106
 
100
107
  // Create ONE stable store instance per key. useRef + lazy init so it is never
101
108
  // recreated on re-render. `key` MUST be stable (document this invariant above).
102
109
  // The storage key becomes `basalt:form:<key>` (createPersistedState auto-namespaces `basalt:*`).
103
- type DraftEnvelope = { values: Values } | null
104
- const storeRef = useRef<ReturnType<typeof createPersistedState<DraftEnvelope>> | null>(null)
110
+ const storeRef = useRef<ReturnType<typeof createPersistedState<DraftEnvelope<Values>>> | null>(
111
+ null,
112
+ )
105
113
  if (storeRef.current === null) {
106
- // Wrap the Values schema into a DraftEnvelope schema using the ~standard interface.
107
- // We validate the inner `values` field so stale/invalid drafts fall back to null.
108
- // Only created when schema is provided — exactOptionalPropertyTypes forbids `schema: undefined`.
109
- const envelopeSchema: StandardSchemaV1<unknown, DraftEnvelope> | undefined =
110
- schema !== undefined
111
- ? {
112
- '~standard': {
113
- version: 1 as const,
114
- vendor: 'basalt-form-draft',
115
- validate: (raw: unknown) => {
116
- if (typeof raw !== 'object' || raw === null || !('values' in raw)) {
117
- return { value: null }
118
- }
119
- const result = schema['~standard'].validate((raw as { values: unknown }).values)
120
- if (result instanceof Promise) return { value: null }
121
- if (result.issues !== undefined) return { value: null }
122
- return { value: { values: result.value } }
123
- },
124
- },
125
- }
126
- : undefined
127
-
128
- storeRef.current = createPersistedState<DraftEnvelope>({
114
+ const envelopeSchema = wrapEnvelopeSchema(schema)
115
+ storeRef.current = createPersistedState<DraftEnvelope<Values>>({
129
116
  key: `form:${key}`,
130
117
  version,
131
118
  initial: null,
119
+ // exactOptionalPropertyTypes forbids `schema: undefined`, so it is spread or omitted.
132
120
  ...(envelopeSchema !== undefined && { schema: envelopeSchema }),
133
121
  })
134
122
  }
@@ -166,5 +154,109 @@ export function useFormDraft<Values extends Record<string, unknown>>(
166
154
  setDraft(null)
167
155
  }
168
156
 
157
+ useAutosave(form, autosave, saveDraft)
158
+
169
159
  return { hasDraft, saveDraft, clearDraft }
170
160
  }
161
+
162
+ // ── the two pieces the hook composes ─────────────────────────────────────────
163
+
164
+ /** What `createPersistedState` stores: the values under one key, or nothing persisted at all. */
165
+ type DraftEnvelope<Values> = { values: Values } | null
166
+
167
+ /**
168
+ * Lifts a `Values` schema into a `DraftEnvelope<Values>` one, through the `~standard` interface.
169
+ *
170
+ * Only the inner `values` field is validated, and every failure resolves to `null` rather than to an
171
+ * issue list: a draft is a convenience, so a stale or hand-edited one is DROPPED, never surfaced as
172
+ * a validation error against a form the user has not touched yet. The async arm resolves to `null`
173
+ * for the same reason `useBasaltForm` pins `sync: true` — `createPersistedState` reads storage
174
+ * synchronously and has nowhere to await.
175
+ *
176
+ * Outside the hook because it is pure, closes over nothing, and inside it read as a third
177
+ * responsibility in a body that already owned the store, the restore and the autosave.
178
+ */
179
+ function wrapEnvelopeSchema<Values>(
180
+ schema: StandardSchemaV1<unknown, Values> | undefined,
181
+ ): StandardSchemaV1<unknown, DraftEnvelope<Values>> | undefined {
182
+ if (schema === undefined) return undefined
183
+ return {
184
+ '~standard': {
185
+ version: 1 as const,
186
+ vendor: 'basalt-form-draft',
187
+ validate: (raw: unknown) => {
188
+ if (typeof raw !== 'object' || raw === null || !('values' in raw)) return { value: null }
189
+ const result = schema['~standard'].validate((raw as { values: unknown }).values)
190
+ if (result instanceof Promise) return { value: null }
191
+ if (result.issues !== undefined) return { value: null }
192
+ return { value: { values: result.value } }
193
+ },
194
+ },
195
+ }
196
+ }
197
+
198
+ /**
199
+ * The debounced `form.watch` subscription behind `autosave`.
200
+ *
201
+ * **It relies on `form.watch` calling exactly one `useEffect` per call**, which is why the watched
202
+ * path set is frozen on the first render: `watch` registers that effect INSIDE itself (checked in
203
+ * the installed `@mantine/form` 9.3.2 source, `use-form-watch.ts`), so the number of `watch` calls
204
+ * IS a hook count and a set that changed between renders would trip React's hook-order invariant.
205
+ * Freezing it is what makes the loop below legal.
206
+ *
207
+ * That is a load-bearing dependency on an implementation detail of a peer, so state it plainly: a
208
+ * `@mantine/form` minor that moves `watch` off `useEffect` — or calls a second hook from it —
209
+ * changes the shape of this file. The failure would be loud (a hook-order error in dev on the first
210
+ * autosaving form), not silent, but it is a real upgrade risk and belongs in the upgrade's diff
211
+ * review rather than in a consumer's bug report.
212
+ *
213
+ * Nested edits need no extra paths: Mantine notifies a parent-path subscriber for an `a.b.c` write,
214
+ * so watching every top-level key watches the whole tree.
215
+ */
216
+ function useAutosave<Values extends Record<string, unknown>>(
217
+ form: UseFormReturnType<Values>,
218
+ autosave: UseFormDraftOptions<Values>['autosave'],
219
+ saveDraft: () => void,
220
+ ): void {
221
+ const watchedPathsRef = useRef<string[] | null>(null)
222
+ if (watchedPathsRef.current === null) {
223
+ watchedPathsRef.current =
224
+ autosave === undefined || autosave === false ? [] : Object.keys(form.getValues())
225
+ }
226
+
227
+ // Read at FIRE time, not at schedule time, so a window that opened three renders ago still writes
228
+ // the current values and the current debounce.
229
+ const debounceRef = useRef(DEFAULT_AUTOSAVE_DEBOUNCE_MS)
230
+ debounceRef.current =
231
+ typeof autosave === 'object'
232
+ ? (autosave.debounceMs ?? DEFAULT_AUTOSAVE_DEBOUNCE_MS)
233
+ : DEFAULT_AUTOSAVE_DEBOUNCE_MS
234
+ // `saveDraft` is a fresh closure each render and `watch`'s effect re-subscribes whenever its
235
+ // callback identity changes, so the callback handed to `watch` must be stable and read the ref.
236
+ const saveRef = useRef<() => void>(saveDraft)
237
+ saveRef.current = saveDraft
238
+
239
+ const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null)
240
+ const scheduleSave = useCallback(() => {
241
+ if (timerRef.current !== null) clearTimeout(timerRef.current)
242
+ timerRef.current = setTimeout(() => {
243
+ timerRef.current = null
244
+ saveRef.current()
245
+ }, debounceRef.current)
246
+ }, [])
247
+
248
+ // An unmount mid-window flushes the pending write rather than dropping it — a closed tab keeps
249
+ // the sentence.
250
+ useEffect(
251
+ () => () => {
252
+ if (timerRef.current !== null) {
253
+ clearTimeout(timerRef.current)
254
+ timerRef.current = null
255
+ saveRef.current()
256
+ }
257
+ },
258
+ [],
259
+ )
260
+
261
+ for (const path of watchedPathsRef.current) form.watch(path, scheduleSave)
262
+ }
@@ -0,0 +1,199 @@
1
+ /**
2
+ * ./forms — useFormSubmit: the submit lifecycle Mantine leaves to every call site.
3
+ * Mantine-coupled. Optional peer: @mantine/form.
4
+ *
5
+ * The gap (audit B §4): `form.onSubmit` gives you validation and a `submitting` flag and nothing
6
+ * else. A real submit also has to catch the handler's throw, turn it into a message a human can
7
+ * read, route a server's per-FIELD errors back onto the fields, and put the caret on the first
8
+ * thing that is wrong. Four jobs, re-written per form, and the last one is the one everybody skips.
9
+ */
10
+ import { useCallback, useRef, useState } from 'react'
11
+ import type { SyntheticEvent } from 'react'
12
+ import type { UseFormReturnType } from '@mantine/form'
13
+ import { toErrorMessage } from '../common/errors'
14
+
15
+ // ── The server field-error envelope ───────────────────────────────────────────
16
+
17
+ /**
18
+ * Per-field messages keyed by the same dotted paths `inputProps(form, path)` uses
19
+ * (`'email'`, `'addresses.0.city'`). The shape a server returns for a 422, and the shape
20
+ * `validateAsync` returns for a uniqueness check.
21
+ */
22
+ export type FormFieldErrors = Record<string, string>
23
+
24
+ /**
25
+ * Whether a thrown value carries `{ fieldErrors }` — the envelope `useFormSubmit` routes back onto
26
+ * the fields instead of into one form-level message.
27
+ *
28
+ * Structural, not `instanceof`: the throw crosses a transport (Eden, `fetch`, a mutation wrapper)
29
+ * and arrives as a plain object, so an `Error` subclass would only match the one shape basalt
30
+ * itself constructed. The keys are checked to be STRINGS — a `{ fieldErrors: { email: 422 } }`
31
+ * would otherwise reach `form.setErrors` and render a number under an input.
32
+ *
33
+ * @example
34
+ * throw Object.assign(new Error('Validation failed'), { fieldErrors: { email: 'Already taken' } })
35
+ */
36
+ export function isFieldErrorEnvelope(err: unknown): err is { fieldErrors: FormFieldErrors } {
37
+ if (err === null || typeof err !== 'object') return false
38
+ const fieldErrors = (err as { fieldErrors?: unknown }).fieldErrors
39
+ if (fieldErrors === null || typeof fieldErrors !== 'object' || Array.isArray(fieldErrors)) {
40
+ return false
41
+ }
42
+ return Object.values(fieldErrors).every((message) => typeof message === 'string')
43
+ }
44
+
45
+ // ── Focus-first-error ─────────────────────────────────────────────────────────
46
+
47
+ /**
48
+ * Puts the caret on the first errored field. `form.getInputNode(path)` is Mantine v9's own lookup
49
+ * (a `[data-path]` query over the attribute `getInputProps` writes, verified in the installed
50
+ * 9.3.2 source); the `[name]` query is the fallback for a control that spreads its own props and
51
+ * never got the attribute.
52
+ *
53
+ * Order is the ERROR RECORD's key order, not the DOM's: Mantine builds it from the schema, so it is
54
+ * the order the fields were declared in — which for a form written top-to-bottom is the visual
55
+ * order, and unlike a DOM sweep it costs no traversal.
56
+ *
57
+ * A no-op without a document (SSR), because `getInputNode` reaches straight for `document`.
58
+ */
59
+ function focusFirstError<Values extends Record<string, unknown>>(
60
+ form: UseFormReturnType<Values>,
61
+ errors: Record<string, unknown>,
62
+ ): void {
63
+ if (typeof document === 'undefined') return
64
+ for (const [path, message] of Object.entries(errors)) {
65
+ if (message === null || message === undefined || message === false) continue
66
+ const node =
67
+ form.getInputNode<HTMLElement, string>(path) ??
68
+ document.querySelector<HTMLElement>(`[name="${path}"]`)
69
+ if (node !== null) {
70
+ node.focus()
71
+ return
72
+ }
73
+ }
74
+ }
75
+
76
+ // ── useFormSubmit ─────────────────────────────────────────────────────────────
77
+
78
+ export type UseFormSubmitOptions<Values extends Record<string, unknown>> = {
79
+ /** Ran after the handler resolves. The success path — close the modal, clear the draft, navigate. */
80
+ onSuccess?: (values: Values) => void
81
+ /** Ran on any throw, after `submitError` is set. For telemetry or a toast; not required for either. */
82
+ onError?: (err: unknown) => void
83
+ /**
84
+ * Turns a thrown value into the message `submitError` carries. Defaults to `toErrorMessage`
85
+ * (`basalt-ui/query`), which already unwraps `Error`, `{ message }` and Eden's `{ status, value }`.
86
+ * Override it to brand the copy or to branch on `errorStatus(err)`.
87
+ */
88
+ mapError?: (err: unknown) => string
89
+ /**
90
+ * The async half of validation, run AFTER the schema passes and BEFORE the handler — a uniqueness
91
+ * check, a server-side cross-field rule, anything that needs the network.
92
+ *
93
+ * It lives here rather than on `useBasaltForm` because that hook hard-codes
94
+ * `schemaResolver(schema, { sync: true })` so `validate()`/`isValid()` stay synchronous for every
95
+ * field-level read. Moving the async rule to submit time keeps that property AND gives the rule a
96
+ * home; the cost, stated plainly, is that it does not run on blur.
97
+ *
98
+ * Return `null` (or an empty record) for "valid". Anything else is set on the fields, the first
99
+ * one is focused, and the handler never runs.
100
+ */
101
+ validateAsync?: (values: Values) => Promise<FormFieldErrors | null>
102
+ }
103
+
104
+ export type UseFormSubmitReturn = {
105
+ /** Hand straight to `<form onSubmit={submit}>`, or call it from a button's `onClick`. */
106
+ submit: (event?: SyntheticEvent<HTMLFormElement>) => void
107
+ /** True from the moment a submit starts until the handler settles. Mantine's own `form.submitting`. */
108
+ isSubmitting: boolean
109
+ /** The form-level failure message, or `null`. Cleared at the start of every submit. */
110
+ submitError: string | null
111
+ /** Clears `submitError` without submitting — for a "dismiss" on the error banner. */
112
+ reset: () => void
113
+ }
114
+
115
+ /**
116
+ * Wraps `form.onSubmit` with the four things a real submit needs: a busy flag, a caught and decoded
117
+ * error, a server field-error envelope routed back onto the fields, and focus on the first thing
118
+ * that is wrong.
119
+ *
120
+ * **`isSubmitting` IS `form.submitting`**, not a second piece of state beside it. Mantine already
121
+ * flips that flag around a handler returning a promise, and this handler always does; duplicating it
122
+ * would give a form two busy flags that can disagree, which is the failure a `FormStateProvider`
123
+ * reading the wrong one produces.
124
+ *
125
+ * **Focus moves on BOTH failure paths** — a schema failure (through `onSubmit`'s own
126
+ * `handleValidationFailure`) and a thrown `{ fieldErrors }` envelope. A server's 422 lands exactly
127
+ * where a client-side error does.
128
+ *
129
+ * @example
130
+ * const { submit, isSubmitting, submitError } = useFormSubmit(
131
+ * form,
132
+ * async (values) => { await unwrap(api.users.post({ body: values })) },
133
+ * { onSuccess: () => { clearDraft(); close() }, validateAsync: checkHandleFree },
134
+ * )
135
+ *
136
+ * <form onSubmit={submit}>
137
+ * <FormStateProvider submitting={isSubmitting}>
138
+ * {submitError !== null && <Alert color="red">{submitError}</Alert>}
139
+ * …
140
+ * </FormStateProvider>
141
+ * </form>
142
+ */
143
+ export function useFormSubmit<Values extends Record<string, unknown>>(
144
+ form: UseFormReturnType<Values>,
145
+ handler: (values: Values) => void | Promise<void>,
146
+ options: UseFormSubmitOptions<Values> = {},
147
+ ): UseFormSubmitReturn {
148
+ const [submitError, setSubmitError] = useState<string | null>(null)
149
+
150
+ // The handler and the callbacks are read at FIRE time, never captured into a memo: a submit
151
+ // handler closes over the freshest props by definition, and a stale one here would post the
152
+ // previous render's values.
153
+ const handlerRef = useRef(handler)
154
+ handlerRef.current = handler
155
+ const optionsRef = useRef(options)
156
+ optionsRef.current = options
157
+ const formRef = useRef(form)
158
+ formRef.current = form
159
+
160
+ const submit = form.onSubmit(
161
+ async (values) => {
162
+ const { onSuccess, onError, mapError, validateAsync } = optionsRef.current
163
+ setSubmitError(null)
164
+ try {
165
+ const fieldErrors = await validateAsync?.(values)
166
+ if (fieldErrors !== undefined && fieldErrors !== null && hasEntries(fieldErrors)) {
167
+ applyFieldErrors(formRef.current, fieldErrors)
168
+ return
169
+ }
170
+ await handlerRef.current(values)
171
+ onSuccess?.(values)
172
+ } catch (err) {
173
+ // Both, not either: the envelope's per-field messages go on the fields AND its decoded
174
+ // message goes in the banner. A 422 whose fields are all off-screen would otherwise report
175
+ // nothing at all where the user is looking.
176
+ if (isFieldErrorEnvelope(err)) applyFieldErrors(formRef.current, err.fieldErrors)
177
+ setSubmitError(mapError === undefined ? toErrorMessage(err) : mapError(err))
178
+ onError?.(err)
179
+ }
180
+ },
181
+ (errors) => focusFirstError(formRef.current, errors),
182
+ )
183
+
184
+ const reset = useCallback(() => setSubmitError(null), [])
185
+
186
+ return { submit, isSubmitting: form.submitting, submitError, reset }
187
+ }
188
+
189
+ function hasEntries(errors: FormFieldErrors): boolean {
190
+ return Object.keys(errors).length > 0
191
+ }
192
+
193
+ function applyFieldErrors<Values extends Record<string, unknown>>(
194
+ form: UseFormReturnType<Values>,
195
+ fieldErrors: FormFieldErrors,
196
+ ): void {
197
+ form.setErrors(fieldErrors)
198
+ focusFirstError(form, fieldErrors)
199
+ }