basalt-ui 1.27.0 → 1.28.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 (1063) hide show
  1. package/AGENTS.md +23 -23
  2. package/CHANGELOG.md +59 -0
  3. package/MIGRATING.md +613 -20
  4. package/README.md +33 -3
  5. package/agent/rules/basalt-batteries.md +25 -10
  6. package/agent/rules/basalt-controls.md +56 -31
  7. package/agent/rules/basalt-mantine.md +17 -6
  8. package/agent/rules/basalt-tokens.md +1 -1
  9. package/configs/oxlint-plugin.js +1056 -28
  10. package/configs/oxlint-plugin.test.ts +1066 -0
  11. package/configs/oxlint.json +7 -0
  12. package/dist/agent/coalesce.d.ts.map +1 -1
  13. package/dist/agent/coalesce.js +2 -1
  14. package/dist/agent/merge.d.ts.map +1 -1
  15. package/dist/agent/merge.js +2 -1
  16. package/dist/agent/part-list.d.ts.map +1 -1
  17. package/dist/agent/part-list.js +2 -0
  18. package/dist/agent/stick-to-bottom.d.ts +3 -6
  19. package/dist/agent/stick-to-bottom.d.ts.map +1 -1
  20. package/dist/agent/stick-to-bottom.js +6 -3
  21. package/dist/agent-chat/composer.d.ts +6 -2
  22. package/dist/agent-chat/composer.d.ts.map +1 -1
  23. package/dist/agent-chat/composer.js +49 -33
  24. package/dist/agent-chat/relative-time.d.ts +0 -9
  25. package/dist/agent-chat/relative-time.d.ts.map +1 -1
  26. package/dist/agent-chat/relative-time.js +2 -1
  27. package/dist/agent-chat/thread-detail-panel.d.ts +3 -2
  28. package/dist/agent-chat/thread-detail-panel.d.ts.map +1 -1
  29. package/dist/agent-chat/thread-detail-panel.js +8 -5
  30. package/dist/agent-chat/thread-feed-row.d.ts +2 -1
  31. package/dist/agent-chat/thread-feed-row.d.ts.map +1 -1
  32. package/dist/agent-chat/thread-feed-row.js +92 -92
  33. package/dist/agent-chat/thread-feed.d.ts +3 -2
  34. package/dist/agent-chat/thread-feed.d.ts.map +1 -1
  35. package/dist/agent-chat/thread-feed.js +8 -3
  36. package/dist/agent-chat/thread-message.d.ts +4 -3
  37. package/dist/agent-chat/thread-message.d.ts.map +1 -1
  38. package/dist/agent-chat/thread-message.js +70 -31
  39. package/dist/agent-chat/thread-outcome-card.d.ts +3 -2
  40. package/dist/agent-chat/thread-outcome-card.d.ts.map +1 -1
  41. package/dist/agent-chat/thread-outcome-card.js +9 -2
  42. package/dist/agent-chat/thread-workspace.d.ts +7 -2
  43. package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
  44. package/dist/agent-chat/thread-workspace.js +62 -29
  45. package/dist/agent-chat/tool-chip.d.ts +3 -2
  46. package/dist/agent-chat/tool-chip.d.ts.map +1 -1
  47. package/dist/agent-chat/tool-chip.js +7 -2
  48. package/dist/charts/hooks/useBandPlot.d.ts.map +1 -1
  49. package/dist/charts/hooks/useBandPlot.js +15 -8
  50. package/dist/charts/index.d.ts +8 -7
  51. package/dist/charts/index.d.ts.map +1 -1
  52. package/dist/charts/index.js +45 -5
  53. package/dist/charts/kinds/BandStrip.d.ts +10 -7
  54. package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
  55. package/dist/charts/kinds/BandStrip.js +12 -7
  56. package/dist/charts/kinds/Bars.d.ts +12 -6
  57. package/dist/charts/kinds/Bars.d.ts.map +1 -1
  58. package/dist/charts/kinds/Bars.js +37 -11
  59. package/dist/charts/kinds/Donut.d.ts +6 -5
  60. package/dist/charts/kinds/Donut.d.ts.map +1 -1
  61. package/dist/charts/kinds/Donut.js +19 -2
  62. package/dist/charts/kinds/DualPanel.d.ts +6 -5
  63. package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
  64. package/dist/charts/kinds/DualPanel.js +36 -8
  65. package/dist/charts/kinds/Heatmap.d.ts +10 -6
  66. package/dist/charts/kinds/Heatmap.d.ts.map +1 -1
  67. package/dist/charts/kinds/Heatmap.js +58 -31
  68. package/dist/charts/kinds/MirroredBars.d.ts +6 -5
  69. package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
  70. package/dist/charts/kinds/MirroredBars.js +9 -2
  71. package/dist/charts/kinds/MultiLine.d.ts +11 -6
  72. package/dist/charts/kinds/MultiLine.d.ts.map +1 -1
  73. package/dist/charts/kinds/MultiLine.js +24 -15
  74. package/dist/charts/kinds/StackedArea.d.ts +18 -8
  75. package/dist/charts/kinds/StackedArea.d.ts.map +1 -1
  76. package/dist/charts/kinds/StackedArea.js +29 -4
  77. package/dist/charts/kinds/ZonedLine.d.ts +12 -8
  78. package/dist/charts/kinds/ZonedLine.d.ts.map +1 -1
  79. package/dist/charts/kinds/ZonedLine.js +33 -23
  80. package/dist/charts/layout/auto-margin.d.ts +65 -8
  81. package/dist/charts/layout/auto-margin.d.ts.map +1 -1
  82. package/dist/charts/layout/auto-margin.js +45 -10
  83. package/dist/charts/layout/log-ticks.d.ts +27 -0
  84. package/dist/charts/layout/log-ticks.d.ts.map +1 -0
  85. package/dist/charts/layout/log-ticks.js +42 -0
  86. package/dist/charts/primitives/Axes.d.ts +11 -2
  87. package/dist/charts/primitives/Axes.d.ts.map +1 -1
  88. package/dist/charts/primitives/Axes.js +15 -5
  89. package/dist/charts/primitives/CartesianChart.d.ts +45 -7
  90. package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
  91. package/dist/charts/primitives/CartesianChart.js +86 -28
  92. package/dist/charts/primitives/ChartCard.d.ts +27 -2
  93. package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
  94. package/dist/charts/primitives/ChartCard.js +37 -17
  95. package/dist/charts/primitives/ChartFrame.d.ts +30 -4
  96. package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
  97. package/dist/charts/primitives/ChartFrame.js +45 -15
  98. package/dist/charts/primitives/ChartLegend.d.ts +13 -2
  99. package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
  100. package/dist/charts/primitives/ChartLegend.js +33 -13
  101. package/dist/charts/primitives/ChartPending.d.ts +77 -4
  102. package/dist/charts/primitives/ChartPending.d.ts.map +1 -1
  103. package/dist/charts/primitives/ChartPending.js +100 -6
  104. package/dist/charts/primitives/ChartTooltip.d.ts +7 -0
  105. package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
  106. package/dist/charts/primitives/ChartTooltip.js +18 -5
  107. package/dist/charts/primitives/Crosshair.d.ts +3 -0
  108. package/dist/charts/primitives/Crosshair.d.ts.map +1 -1
  109. package/dist/charts/primitives/Crosshair.js +3 -1
  110. package/dist/charts/primitives/chart-frame-layout.d.ts +95 -0
  111. package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -0
  112. package/dist/charts/primitives/chart-frame-layout.js +89 -0
  113. package/dist/charts/primitives/chart-tier.d.ts +16 -0
  114. package/dist/charts/primitives/chart-tier.d.ts.map +1 -0
  115. package/dist/charts/primitives/chart-tier.js +20 -0
  116. package/dist/charts/series.d.ts +55 -1
  117. package/dist/charts/series.d.ts.map +1 -1
  118. package/dist/charts/series.js +27 -1
  119. package/dist/charts/sparklines/BarSparkline.d.ts +3 -3
  120. package/dist/charts/sparklines/BarSparkline.d.ts.map +1 -1
  121. package/dist/charts/sparklines/BarSparkline.js +9 -3
  122. package/dist/charts/sparklines/LineSparkline.d.ts +3 -3
  123. package/dist/charts/sparklines/LineSparkline.d.ts.map +1 -1
  124. package/dist/charts/sparklines/LineSparkline.js +15 -3
  125. package/dist/charts/sparklines/index.d.ts +2 -2
  126. package/dist/charts/sparklines/index.d.ts.map +1 -1
  127. package/dist/charts/utils/format.d.ts +92 -2
  128. package/dist/charts/utils/format.d.ts.map +1 -1
  129. package/dist/charts/utils/format.js +64 -1
  130. package/dist/charts/utils/ticks.d.ts +81 -2
  131. package/dist/charts/utils/ticks.d.ts.map +1 -1
  132. package/dist/charts/utils/ticks.js +54 -4
  133. package/dist/cli/index.d.ts.map +1 -1
  134. package/dist/cli/index.js +2 -2
  135. package/dist/commands/ShortcutsHelp.d.ts +3 -2
  136. package/dist/commands/ShortcutsHelp.d.ts.map +1 -1
  137. package/dist/commands/ShortcutsHelp.js +8 -2
  138. package/dist/commands/define-commands.d.ts.map +1 -1
  139. package/dist/commands/define-commands.js +2 -2
  140. package/dist/commands/define-overlays.d.ts +102 -0
  141. package/dist/commands/define-overlays.d.ts.map +1 -1
  142. package/dist/commands/define-overlays.js +102 -2
  143. package/dist/commands/index.d.ts +10 -1
  144. package/dist/commands/index.d.ts.map +1 -1
  145. package/dist/commands/index.js +3 -1
  146. package/dist/commands/overlays-mount.d.ts +13 -6
  147. package/dist/commands/overlays-mount.d.ts.map +1 -1
  148. package/dist/commands/overlays-mount.js +23 -14
  149. package/dist/common/errors.d.ts +34 -0
  150. package/dist/common/errors.d.ts.map +1 -0
  151. package/dist/common/errors.js +36 -0
  152. package/dist/common/index.d.ts +15 -0
  153. package/dist/common/index.d.ts.map +1 -0
  154. package/dist/common/index.js +29 -0
  155. package/dist/common/props.d.ts +63 -0
  156. package/dist/common/props.d.ts.map +1 -0
  157. package/dist/common/props.js +6 -0
  158. package/dist/common/query-state-like.d.ts +43 -0
  159. package/dist/common/query-state-like.d.ts.map +1 -0
  160. package/dist/common/query-state-like.js +20 -0
  161. package/dist/common/refs.d.ts +29 -0
  162. package/dist/common/refs.d.ts.map +1 -0
  163. package/dist/common/refs.js +29 -0
  164. package/dist/common/scroll-parent.d.ts +23 -0
  165. package/dist/common/scroll-parent.d.ts.map +1 -0
  166. package/dist/common/scroll-parent.js +21 -0
  167. package/dist/common/validate.d.ts +38 -0
  168. package/dist/common/validate.d.ts.map +1 -0
  169. package/dist/common/validate.js +36 -0
  170. package/dist/connectivity/connectivity-indicator.d.ts +3 -1
  171. package/dist/connectivity/connectivity-indicator.d.ts.map +1 -1
  172. package/dist/connectivity/connectivity-indicator.js +3 -1
  173. package/dist/connectivity/connectivity-provider.d.ts.map +1 -1
  174. package/dist/connectivity/connectivity-provider.js +4 -1
  175. package/dist/connectivity/index.d.ts +1 -0
  176. package/dist/connectivity/index.d.ts.map +1 -1
  177. package/dist/connectivity/types.d.ts +2 -2
  178. package/dist/connectivity/types.d.ts.map +1 -1
  179. package/dist/connectivity/use-connectivity.d.ts.map +1 -1
  180. package/dist/content/article-layout.module.css +11 -4
  181. package/dist/content/callout.d.ts +8 -4
  182. package/dist/content/callout.d.ts.map +1 -1
  183. package/dist/content/callout.js +15 -8
  184. package/dist/content/guide.d.ts +5 -4
  185. package/dist/content/guide.d.ts.map +1 -1
  186. package/dist/content/guide.js +13 -4
  187. package/dist/content/heading-anchor.d.ts +24 -2
  188. package/dist/content/heading-anchor.d.ts.map +1 -1
  189. package/dist/content/heading-anchor.js +23 -9
  190. package/dist/content/index.d.ts.map +1 -1
  191. package/dist/content/markdown.d.ts.map +1 -1
  192. package/dist/content/markdown.js +2 -0
  193. package/dist/content/prose.module.css +9 -7
  194. package/dist/content/reading-progress.d.ts +10 -4
  195. package/dist/content/reading-progress.d.ts.map +1 -1
  196. package/dist/content/reading-progress.js +26 -10
  197. package/dist/content/slug.d.ts +4 -0
  198. package/dist/content/slug.d.ts.map +1 -1
  199. package/dist/content/toc.d.ts +11 -0
  200. package/dist/content/toc.d.ts.map +1 -1
  201. package/dist/content/toc.js +23 -10
  202. package/dist/controls/actions.d.ts +49 -6
  203. package/dist/controls/actions.d.ts.map +1 -1
  204. package/dist/controls/actions.js +39 -8
  205. package/dist/controls/compare-filter.d.ts +3 -2
  206. package/dist/controls/compare-filter.d.ts.map +1 -1
  207. package/dist/controls/compare-filter.js +17 -2
  208. package/dist/controls/control-group.d.ts +3 -3
  209. package/dist/controls/control-group.d.ts.map +1 -1
  210. package/dist/controls/control-group.js +9 -2
  211. package/dist/controls/controls.module.css +169 -186
  212. package/dist/controls/controls.module.css.d.ts +9 -11
  213. package/dist/controls/enum-filter.d.ts +3 -2
  214. package/dist/controls/enum-filter.d.ts.map +1 -1
  215. package/dist/controls/enum-filter.js +28 -13
  216. package/dist/controls/filter-context.d.ts +8 -4
  217. package/dist/controls/filter-context.d.ts.map +1 -1
  218. package/dist/controls/filter-pill.d.ts +3 -3
  219. package/dist/controls/filter-pill.d.ts.map +1 -1
  220. package/dist/controls/filter-pill.js +4 -1
  221. package/dist/controls/filter-set.d.ts +3 -2
  222. package/dist/controls/filter-set.d.ts.map +1 -1
  223. package/dist/controls/filter-set.js +66 -41
  224. package/dist/controls/filter-sheet.d.ts +20 -80
  225. package/dist/controls/filter-sheet.d.ts.map +1 -1
  226. package/dist/controls/filter-sheet.js +9 -95
  227. package/dist/controls/index.d.ts +2 -0
  228. package/dist/controls/index.d.ts.map +1 -1
  229. package/dist/controls/index.js +4 -0
  230. package/dist/controls/multi-select-filter.d.ts +18 -2
  231. package/dist/controls/multi-select-filter.d.ts.map +1 -1
  232. package/dist/controls/multi-select-filter.js +122 -20
  233. package/dist/controls/number-filter.d.ts +7 -5
  234. package/dist/controls/number-filter.d.ts.map +1 -1
  235. package/dist/controls/number-filter.js +40 -11
  236. package/dist/controls/panel-row.d.ts +132 -0
  237. package/dist/controls/panel-row.d.ts.map +1 -0
  238. package/dist/controls/panel-row.js +173 -0
  239. package/dist/controls/panel-row.module.css +86 -0
  240. package/dist/controls/panel-row.module.css.d.ts +13 -0
  241. package/dist/controls/range-filter.d.ts +2 -1
  242. package/dist/controls/range-filter.d.ts.map +1 -1
  243. package/dist/controls/range-filter.js +57 -35
  244. package/dist/controls/search-filter.d.ts +3 -2
  245. package/dist/controls/search-filter.d.ts.map +1 -1
  246. package/dist/controls/search-filter.js +25 -10
  247. package/dist/controls/select-filter.d.ts +2 -1
  248. package/dist/controls/select-filter.d.ts.map +1 -1
  249. package/dist/controls/select-filter.js +4 -0
  250. package/dist/controls/slider-control.d.ts +36 -0
  251. package/dist/controls/slider-control.d.ts.map +1 -0
  252. package/dist/controls/slider-control.js +64 -0
  253. package/dist/controls/sync-button.d.ts +3 -2
  254. package/dist/controls/sync-button.d.ts.map +1 -1
  255. package/dist/controls/sync-button.js +16 -3
  256. package/dist/controls/toggle-filter.d.ts +3 -2
  257. package/dist/controls/toggle-filter.d.ts.map +1 -1
  258. package/dist/controls/toggle-filter.js +28 -11
  259. package/dist/controls/view-tabs.d.ts +3 -2
  260. package/dist/controls/view-tabs.d.ts.map +1 -1
  261. package/dist/controls/view-tabs.js +43 -11
  262. package/dist/controls-dates/date-range-picker.d.ts +1 -1
  263. package/dist/controls-dates/date-range-picker.d.ts.map +1 -1
  264. package/dist/controls-dates/date-range-picker.js +6 -1
  265. package/dist/dashboard/delta-badge.d.ts +5 -1
  266. package/dist/dashboard/delta-badge.d.ts.map +1 -1
  267. package/dist/dashboard/empty-state.d.ts +10 -3
  268. package/dist/dashboard/empty-state.d.ts.map +1 -1
  269. package/dist/dashboard/empty-state.js +37 -6
  270. package/dist/dashboard/index.d.ts +6 -4
  271. package/dist/dashboard/index.d.ts.map +1 -1
  272. package/dist/dashboard/index.js +7 -1
  273. package/dist/dashboard/query-state.d.ts +48 -27
  274. package/dist/dashboard/query-state.d.ts.map +1 -1
  275. package/dist/dashboard/query-state.js +111 -57
  276. package/dist/dashboard/settings-section.d.ts +19 -9
  277. package/dist/dashboard/settings-section.d.ts.map +1 -1
  278. package/dist/dashboard/settings-section.js +74 -25
  279. package/dist/dashboard/stat-card.d.ts +44 -38
  280. package/dist/dashboard/stat-card.d.ts.map +1 -1
  281. package/dist/dashboard/stat-card.js +55 -42
  282. package/dist/dashboard/stat-card.module.css +46 -31
  283. package/dist/dashboard/stat-card.module.css.d.ts +1 -0
  284. package/dist/dashboard/stat-group.d.ts +41 -0
  285. package/dist/dashboard/stat-group.d.ts.map +1 -0
  286. package/dist/dashboard/stat-group.js +30 -0
  287. package/dist/dashboard/stat-group.module.css +66 -0
  288. package/dist/dashboard/stat-group.module.css.d.ts +8 -0
  289. package/dist/dashboard/widget-grid.d.ts +27 -0
  290. package/dist/dashboard/widget-grid.d.ts.map +1 -0
  291. package/dist/dashboard/widget-grid.js +41 -0
  292. package/dist/dashboard/widget-grid.module.css +53 -0
  293. package/dist/dashboard/widget-grid.module.css.d.ts +9 -0
  294. package/dist/data/data-table.d.ts +151 -12
  295. package/dist/data/data-table.d.ts.map +1 -1
  296. package/dist/data/data-table.js +384 -138
  297. package/dist/data/data-table.module.css +64 -0
  298. package/dist/data/data-table.module.css.d.ts +11 -0
  299. package/dist/data/index.d.ts +2 -2
  300. package/dist/data/index.d.ts.map +1 -1
  301. package/dist/data/index.js +24 -2
  302. package/dist/data/query-branch.d.ts +28 -0
  303. package/dist/data/query-branch.d.ts.map +1 -0
  304. package/dist/data/query-branch.js +10 -0
  305. package/dist/data/table.d.ts +2 -2
  306. package/dist/data/table.d.ts.map +1 -1
  307. package/dist/data/virtual-list.d.ts +65 -6
  308. package/dist/data/virtual-list.d.ts.map +1 -1
  309. package/dist/data/virtual-list.js +89 -38
  310. package/dist/data/virtual.d.ts +1 -1
  311. package/dist/data/virtual.d.ts.map +1 -1
  312. package/dist/forms/FormErrorSummary.d.ts +4 -3
  313. package/dist/forms/FormErrorSummary.d.ts.map +1 -1
  314. package/dist/forms/FormErrorSummary.js +6 -4
  315. package/dist/forms/create-form.d.ts +2 -2
  316. package/dist/forms/field.d.ts +46 -6
  317. package/dist/forms/field.d.ts.map +1 -1
  318. package/dist/forms/field.js +10 -5
  319. package/dist/forms/form-layout.d.ts +142 -0
  320. package/dist/forms/form-layout.d.ts.map +1 -0
  321. package/dist/forms/form-layout.js +110 -0
  322. package/dist/forms/form-layout.module.css +145 -0
  323. package/dist/forms/form-layout.module.css.d.ts +20 -0
  324. package/dist/forms/form-state.d.ts +42 -0
  325. package/dist/forms/form-state.d.ts.map +1 -0
  326. package/dist/forms/form-state.js +26 -0
  327. package/dist/forms/index.d.ts +22 -6
  328. package/dist/forms/index.d.ts.map +1 -1
  329. package/dist/forms/index.js +19 -3
  330. package/dist/forms/use-field-array.d.ts +60 -0
  331. package/dist/forms/use-field-array.d.ts.map +1 -0
  332. package/dist/forms/use-field-array.js +20 -0
  333. package/dist/forms/use-form-draft.d.ts +25 -10
  334. package/dist/forms/use-form-draft.d.ts.map +1 -1
  335. package/dist/forms/use-form-draft.js +55 -18
  336. package/dist/forms/use-form-submit.d.ts +88 -0
  337. package/dist/forms/use-form-submit.d.ts.map +1 -0
  338. package/dist/forms/use-form-submit.js +63 -0
  339. package/dist/guard/index.d.ts.map +1 -1
  340. package/dist/guard/index.js +26 -6
  341. package/dist/index.d.ts +10 -8
  342. package/dist/index.d.ts.map +1 -1
  343. package/dist/index.js +44 -4
  344. package/dist/nav/types.d.ts +15 -6
  345. package/dist/nav/types.d.ts.map +1 -1
  346. package/dist/notifications/bell.d.ts +3 -2
  347. package/dist/notifications/bell.d.ts.map +1 -1
  348. package/dist/notifications/bell.js +73 -56
  349. package/dist/notifications/center.d.ts +15 -4
  350. package/dist/notifications/center.d.ts.map +1 -1
  351. package/dist/notifications/center.js +5 -2
  352. package/dist/notifications/define-notifications.d.ts +56 -14
  353. package/dist/notifications/define-notifications.d.ts.map +1 -1
  354. package/dist/notifications/define-notifications.js +2 -1
  355. package/dist/notifications/index.d.ts +6 -2
  356. package/dist/notifications/index.d.ts.map +1 -1
  357. package/dist/notifications/index.js +5 -1
  358. package/dist/notifications/mount-guard.d.ts +8 -0
  359. package/dist/notifications/mount-guard.d.ts.map +1 -0
  360. package/dist/notifications/mount-guard.js +19 -0
  361. package/dist/notifications/notify.d.ts +58 -1
  362. package/dist/notifications/notify.d.ts.map +1 -1
  363. package/dist/notifications/notify.js +46 -2
  364. package/dist/notifications/overlay.d.ts.map +1 -1
  365. package/dist/notifications/overlay.js +2 -0
  366. package/dist/notifications/store.d.ts +7 -0
  367. package/dist/notifications/store.d.ts.map +1 -1
  368. package/dist/provider/index.d.ts +37 -5
  369. package/dist/provider/index.d.ts.map +1 -1
  370. package/dist/provider/index.js +66 -28
  371. package/dist/provider/lab-theme.d.ts.map +1 -1
  372. package/dist/provider/lab-theme.js +2 -1
  373. package/dist/query/devtools.d.ts.map +1 -1
  374. package/dist/query/devtools.js +1 -0
  375. package/dist/router-tanstack/field.d.ts +1 -1
  376. package/dist/router-tanstack/field.d.ts.map +1 -1
  377. package/dist/router-tanstack/search-store.d.ts.map +1 -1
  378. package/dist/router-tanstack/search-store.js +1 -1
  379. package/dist/router-tanstack/use-nav.d.ts.map +1 -1
  380. package/dist/router-tanstack/use-nav.js +1 -1
  381. package/dist/section/index.d.ts +1 -1
  382. package/dist/section/index.d.ts.map +1 -1
  383. package/dist/section/section.d.ts +36 -2
  384. package/dist/section/section.d.ts.map +1 -1
  385. package/dist/section/section.js +49 -57
  386. package/dist/section/section.module.css +11 -0
  387. package/dist/shell/account-types.d.ts +5 -2
  388. package/dist/shell/account-types.d.ts.map +1 -1
  389. package/dist/shell/app-brand.d.ts +13 -0
  390. package/dist/shell/app-brand.d.ts.map +1 -0
  391. package/dist/shell/app-brand.js +94 -0
  392. package/dist/shell/app-brand.module.css +109 -0
  393. package/dist/shell/app-brand.module.css.d.ts +14 -0
  394. package/dist/shell/app-breadcrumbs.d.ts +4 -2
  395. package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
  396. package/dist/shell/app-breadcrumbs.js +33 -22
  397. package/dist/shell/app-header.module.css +10 -5
  398. package/dist/shell/app-main.module.css +107 -0
  399. package/dist/shell/app-main.module.css.d.ts +11 -0
  400. package/dist/shell/app-mobile-nav.d.ts +3 -2
  401. package/dist/shell/app-mobile-nav.d.ts.map +1 -1
  402. package/dist/shell/app-mobile-nav.js +29 -15
  403. package/dist/shell/app-mobile-nav.module.css +48 -27
  404. package/dist/shell/app-mobile-nav.module.css.d.ts +0 -1
  405. package/dist/shell/app-sidebar-account.d.ts +2 -1
  406. package/dist/shell/app-sidebar-account.d.ts.map +1 -1
  407. package/dist/shell/app-sidebar-account.js +57 -22
  408. package/dist/shell/app-sidebar.d.ts +9 -3
  409. package/dist/shell/app-sidebar.d.ts.map +1 -1
  410. package/dist/shell/app-sidebar.js +55 -109
  411. package/dist/shell/app-sidebar.module.css +53 -96
  412. package/dist/shell/app-sidebar.module.css.d.ts +0 -5
  413. package/dist/shell/index.d.ts +14 -6
  414. package/dist/shell/index.d.ts.map +1 -1
  415. package/dist/shell/index.js +47 -12
  416. package/dist/shell/isomorphic-layout-effect.d.ts +14 -0
  417. package/dist/shell/isomorphic-layout-effect.d.ts.map +1 -0
  418. package/dist/shell/isomorphic-layout-effect.js +5 -0
  419. package/dist/shell/mobile-nav-model.d.ts.map +1 -1
  420. package/dist/shell/mobile-nav-model.js +27 -6
  421. package/dist/shell/nav-count-badge.d.ts +5 -3
  422. package/dist/shell/nav-count-badge.d.ts.map +1 -1
  423. package/dist/shell/nav-count-badge.js +3 -1
  424. package/dist/shell/page-aside.d.ts +43 -0
  425. package/dist/shell/page-aside.d.ts.map +1 -0
  426. package/dist/shell/page-aside.js +202 -0
  427. package/dist/shell/page-aside.module.css +174 -0
  428. package/dist/shell/page-aside.module.css.d.ts +14 -0
  429. package/dist/shell/page-bar.d.ts +55 -15
  430. package/dist/shell/page-bar.d.ts.map +1 -1
  431. package/dist/shell/page-bar.js +130 -41
  432. package/dist/shell/page-bar.module.css +107 -13
  433. package/dist/shell/page-bar.module.css.d.ts +4 -1
  434. package/dist/shell/sidebar-search.d.ts +4 -2
  435. package/dist/shell/sidebar-search.d.ts.map +1 -1
  436. package/dist/shell/sidebar-search.js +9 -4
  437. package/dist/shell/sidebar-search.module.css +1 -1
  438. package/dist/state/fields.d.ts +23 -3
  439. package/dist/state/fields.d.ts.map +1 -1
  440. package/dist/state/fields.js +13 -2
  441. package/dist/state/persisted-or-local.d.ts +9 -0
  442. package/dist/state/persisted-or-local.d.ts.map +1 -0
  443. package/dist/state/persisted-or-local.js +24 -0
  444. package/dist/state.d.ts +1 -1
  445. package/dist/state.d.ts.map +1 -1
  446. package/dist/state.js +2 -6
  447. package/dist/surfaces.d.ts +12 -11
  448. package/dist/surfaces.d.ts.map +1 -1
  449. package/dist/surfaces.js +42 -12
  450. package/dist/theme/ctl-theme.d.ts.map +1 -1
  451. package/dist/theme/index.d.ts.map +1 -1
  452. package/dist/theme/index.js +102 -17
  453. package/dist/theme/nav-link.module.css +37 -26
  454. package/dist/theme/segmented-control.module.css +22 -0
  455. package/dist/theme/segmented-control.module.css.d.ts +1 -0
  456. package/dist/theme-lab/boot.d.ts +66 -0
  457. package/dist/theme-lab/boot.d.ts.map +1 -0
  458. package/dist/theme-lab/boot.js +82 -0
  459. package/dist/theme-lab/index.d.ts +4 -43
  460. package/dist/theme-lab/index.d.ts.map +1 -1
  461. package/dist/theme-lab/index.js +9 -69
  462. package/dist/theme-toggle/index.d.ts +3 -2
  463. package/dist/theme-toggle/index.d.ts.map +1 -1
  464. package/dist/theme-toggle/index.js +8 -2
  465. package/dist/tokens/index.d.ts +42 -0
  466. package/dist/tokens/index.d.ts.map +1 -1
  467. package/dist/tokens/index.js +35 -6
  468. package/dist/tokens/palette.d.ts +45 -25
  469. package/dist/tokens/palette.d.ts.map +1 -1
  470. package/dist/tokens/palette.js +31 -14
  471. package/dist/tokens.css +4 -5
  472. package/dist/utils/is-dev.d.ts +3 -0
  473. package/dist/utils/is-dev.d.ts.map +1 -0
  474. package/dist/utils/is-dev.js +6 -0
  475. package/dist/widget-header/delta-badge.d.ts +7 -1
  476. package/dist/widget-header/delta-badge.d.ts.map +1 -1
  477. package/dist/widget-header/delta-badge.js +8 -1
  478. package/dist/widget-header/index.d.ts +2 -2
  479. package/dist/widget-header/index.d.ts.map +1 -1
  480. package/dist/widget-header/index.js +3 -1
  481. package/dist/widget-header/widget-header.d.ts +69 -4
  482. package/dist/widget-header/widget-header.d.ts.map +1 -1
  483. package/dist/widget-header/widget-header.js +42 -27
  484. package/dist/widget-header/widget-header.module.css +72 -7
  485. package/llms.txt +6 -6
  486. package/package.json +49 -25
  487. package/src/agent/coalesce.ts +2 -1
  488. package/src/agent/merge.ts +2 -1
  489. package/src/agent/part-list.tsx +2 -0
  490. package/src/agent/stick-to-bottom.tsx +9 -11
  491. package/src/agent-chat/composer.tsx +124 -103
  492. package/src/agent-chat/relative-time.ts +2 -1
  493. package/src/agent-chat/thread-detail-panel.tsx +9 -5
  494. package/src/agent-chat/thread-feed-row.tsx +17 -9
  495. package/src/agent-chat/thread-feed.tsx +9 -3
  496. package/src/agent-chat/thread-message.tsx +48 -13
  497. package/src/agent-chat/thread-outcome-card.tsx +9 -1
  498. package/src/agent-chat/thread-workspace.tsx +72 -33
  499. package/src/agent-chat/tool-chip.tsx +8 -2
  500. package/src/charts/hooks/useBandPlot.ts +26 -8
  501. package/src/charts/index.ts +39 -4
  502. package/src/charts/kinds/BandStrip.tsx +36 -14
  503. package/src/charts/kinds/Bars.tsx +67 -16
  504. package/src/charts/kinds/Donut.tsx +30 -3
  505. package/src/charts/kinds/DualPanel.tsx +56 -10
  506. package/src/charts/kinds/Heatmap.tsx +90 -33
  507. package/src/charts/kinds/MirroredBars.tsx +21 -3
  508. package/src/charts/kinds/MultiLine.tsx +61 -18
  509. package/src/charts/kinds/StackedArea.tsx +77 -6
  510. package/src/charts/kinds/ZonedLine.tsx +71 -31
  511. package/src/charts/layout/auto-margin.ts +134 -21
  512. package/src/charts/layout/log-ticks.ts +90 -0
  513. package/src/charts/primitives/Axes.tsx +33 -5
  514. package/src/charts/primitives/CartesianChart.tsx +194 -41
  515. package/src/charts/primitives/ChartCard.tsx +66 -25
  516. package/src/charts/primitives/ChartFrame.tsx +107 -26
  517. package/src/charts/primitives/ChartLegend.tsx +43 -13
  518. package/src/charts/primitives/ChartPending.tsx +185 -7
  519. package/src/charts/primitives/ChartTooltip.tsx +37 -5
  520. package/src/charts/primitives/Crosshair.tsx +6 -3
  521. package/src/charts/primitives/chart-frame-layout.ts +212 -0
  522. package/src/charts/primitives/chart-tier.tsx +37 -0
  523. package/src/charts/series.ts +77 -1
  524. package/src/charts/sparklines/BarSparkline.tsx +11 -3
  525. package/src/charts/sparklines/LineSparkline.tsx +18 -4
  526. package/src/charts/sparklines/index.ts +2 -2
  527. package/src/charts/utils/format.ts +163 -2
  528. package/src/charts/utils/ticks.ts +149 -4
  529. package/src/cli/index.ts +8 -3
  530. package/src/commands/ShortcutsHelp.tsx +10 -3
  531. package/src/commands/define-commands.ts +2 -2
  532. package/src/commands/define-overlays.ts +216 -1
  533. package/src/commands/index.ts +12 -0
  534. package/src/commands/overlays-mount.tsx +60 -26
  535. package/src/common/errors.ts +73 -0
  536. package/src/common/index.ts +21 -0
  537. package/src/common/props.ts +71 -0
  538. package/src/common/query-state-like.ts +64 -0
  539. package/src/common/refs.ts +58 -0
  540. package/src/common/scroll-parent.ts +42 -0
  541. package/src/common/validate.ts +94 -0
  542. package/src/connectivity/connectivity-indicator.tsx +6 -1
  543. package/src/connectivity/connectivity-provider.tsx +4 -1
  544. package/src/connectivity/index.ts +1 -0
  545. package/src/connectivity/types.ts +5 -2
  546. package/src/connectivity/use-connectivity.ts +3 -2
  547. package/src/content/article-layout.module.css +11 -4
  548. package/src/content/callout.tsx +13 -7
  549. package/src/content/guide.tsx +14 -4
  550. package/src/content/heading-anchor.tsx +14 -3
  551. package/src/content/index.ts +2 -0
  552. package/src/content/markdown.tsx +2 -0
  553. package/src/content/prose.module.css +9 -7
  554. package/src/content/reading-progress.tsx +40 -15
  555. package/src/content/slug.ts +4 -0
  556. package/src/content/toc.tsx +47 -10
  557. package/src/controls/actions.tsx +89 -9
  558. package/src/controls/compare-filter.tsx +20 -3
  559. package/src/controls/control-group.tsx +11 -4
  560. package/src/controls/controls.module.css +169 -186
  561. package/src/controls/controls.module.css.d.ts +9 -11
  562. package/src/controls/enum-filter.tsx +32 -16
  563. package/src/controls/filter-context.tsx +14 -6
  564. package/src/controls/filter-pill.tsx +6 -3
  565. package/src/controls/filter-set.tsx +32 -13
  566. package/src/controls/filter-sheet.tsx +44 -194
  567. package/src/controls/index.ts +7 -0
  568. package/src/controls/multi-select-filter.tsx +177 -27
  569. package/src/controls/number-filter.tsx +61 -23
  570. package/src/controls/panel-row.module.css +86 -0
  571. package/src/controls/panel-row.module.css.d.ts +13 -0
  572. package/src/controls/panel-row.tsx +392 -0
  573. package/src/controls/range-filter.tsx +76 -39
  574. package/src/controls/search-filter.tsx +30 -12
  575. package/src/controls/select-filter.tsx +11 -1
  576. package/src/controls/slider-control.tsx +159 -0
  577. package/src/controls/sync-button.tsx +13 -3
  578. package/src/controls/toggle-filter.tsx +36 -16
  579. package/src/controls/view-tabs.tsx +63 -11
  580. package/src/controls-dates/date-range-picker.tsx +8 -1
  581. package/src/dashboard/delta-badge.tsx +5 -1
  582. package/src/dashboard/empty-state.tsx +72 -25
  583. package/src/dashboard/index.ts +13 -1
  584. package/src/dashboard/query-state.tsx +154 -84
  585. package/src/dashboard/settings-section.tsx +87 -31
  586. package/src/dashboard/stat-card.module.css +46 -31
  587. package/src/dashboard/stat-card.module.css.d.ts +1 -0
  588. package/src/dashboard/stat-card.tsx +185 -127
  589. package/src/dashboard/stat-group.module.css +66 -0
  590. package/src/dashboard/stat-group.module.css.d.ts +8 -0
  591. package/src/dashboard/stat-group.tsx +74 -0
  592. package/src/dashboard/widget-grid.module.css +53 -0
  593. package/src/dashboard/widget-grid.module.css.d.ts +9 -0
  594. package/src/dashboard/widget-grid.tsx +127 -0
  595. package/src/data/data-table.module.css +64 -0
  596. package/src/data/data-table.module.css.d.ts +11 -0
  597. package/src/data/data-table.tsx +919 -346
  598. package/src/data/index.ts +30 -2
  599. package/src/data/query-branch.ts +53 -0
  600. package/src/data/table.ts +5 -0
  601. package/src/data/virtual-list.tsx +189 -55
  602. package/src/data/virtual.ts +5 -1
  603. package/src/forms/FormErrorSummary.tsx +13 -6
  604. package/src/forms/create-form.ts +2 -2
  605. package/src/forms/field.ts +60 -11
  606. package/src/forms/form-layout.module.css +145 -0
  607. package/src/forms/form-layout.module.css.d.ts +20 -0
  608. package/src/forms/form-layout.tsx +305 -0
  609. package/src/forms/form-state.tsx +94 -0
  610. package/src/forms/index.ts +38 -7
  611. package/src/forms/use-field-array.ts +94 -0
  612. package/src/forms/use-form-draft.ts +145 -53
  613. package/src/forms/use-form-submit.ts +199 -0
  614. package/src/guard/index.ts +73 -18
  615. package/src/index.ts +74 -10
  616. package/src/nav/types.ts +15 -6
  617. package/src/notifications/bell.tsx +18 -4
  618. package/src/notifications/center.tsx +18 -5
  619. package/src/notifications/define-notifications.ts +64 -18
  620. package/src/notifications/index.ts +12 -1
  621. package/src/notifications/mount-guard.ts +41 -0
  622. package/src/notifications/notify.tsx +122 -3
  623. package/src/notifications/overlay.tsx +2 -0
  624. package/src/notifications/store.ts +7 -0
  625. package/src/provider/index.tsx +101 -13
  626. package/src/provider/lab-theme.ts +2 -1
  627. package/src/query/devtools.tsx +1 -0
  628. package/src/router-tanstack/field.ts +1 -0
  629. package/src/router-tanstack/search-store.ts +3 -10
  630. package/src/router-tanstack/use-nav.ts +18 -13
  631. package/src/section/index.ts +1 -1
  632. package/src/section/section.module.css +11 -0
  633. package/src/section/section.tsx +163 -96
  634. package/src/shell/account-types.ts +5 -2
  635. package/src/shell/app-brand.module.css +109 -0
  636. package/src/shell/app-brand.module.css.d.ts +14 -0
  637. package/src/shell/app-brand.tsx +140 -0
  638. package/src/shell/app-breadcrumbs.tsx +19 -9
  639. package/src/shell/app-header.module.css +10 -5
  640. package/src/shell/app-main.module.css +107 -0
  641. package/src/shell/app-main.module.css.d.ts +11 -0
  642. package/src/shell/app-mobile-nav.module.css +48 -27
  643. package/src/shell/app-mobile-nav.module.css.d.ts +0 -1
  644. package/src/shell/app-mobile-nav.tsx +43 -11
  645. package/src/shell/app-sidebar-account.tsx +29 -6
  646. package/src/shell/app-sidebar.module.css +53 -96
  647. package/src/shell/app-sidebar.module.css.d.ts +0 -5
  648. package/src/shell/app-sidebar.tsx +40 -113
  649. package/src/shell/index.tsx +156 -65
  650. package/src/shell/isomorphic-layout-effect.ts +14 -0
  651. package/src/shell/mobile-nav-model.ts +66 -10
  652. package/src/shell/nav-count-badge.tsx +6 -1
  653. package/src/shell/page-aside.module.css +174 -0
  654. package/src/shell/page-aside.module.css.d.ts +14 -0
  655. package/src/shell/page-aside.tsx +377 -0
  656. package/src/shell/page-bar.module.css +107 -13
  657. package/src/shell/page-bar.module.css.d.ts +4 -1
  658. package/src/shell/page-bar.tsx +294 -94
  659. package/src/shell/sidebar-search.module.css +1 -1
  660. package/src/shell/sidebar-search.tsx +13 -4
  661. package/src/state/fields.ts +43 -10
  662. package/src/state/persisted-or-local.ts +50 -0
  663. package/src/state.ts +0 -9
  664. package/src/surfaces.ts +42 -12
  665. package/src/theme/ctl-theme.tsx +10 -0
  666. package/src/theme/index.ts +129 -16
  667. package/src/theme/nav-link.module.css +37 -26
  668. package/src/theme/segmented-control.module.css +22 -0
  669. package/src/theme/segmented-control.module.css.d.ts +1 -0
  670. package/src/theme-lab/boot.ts +140 -0
  671. package/src/theme-lab/index.tsx +21 -112
  672. package/src/theme-toggle/index.tsx +10 -3
  673. package/src/tokens/index.ts +50 -6
  674. package/src/tokens/palette.ts +58 -30
  675. package/src/utils/is-dev.ts +4 -0
  676. package/src/widget-header/delta-badge.tsx +25 -5
  677. package/src/widget-header/index.ts +10 -2
  678. package/src/widget-header/widget-header.module.css +72 -7
  679. package/src/widget-header/widget-header.tsx +150 -71
  680. package/dist/agent/adapter.test.d.ts +0 -2
  681. package/dist/agent/adapter.test.d.ts.map +0 -1
  682. package/dist/agent/ai-sdk-transport.test.d.ts +0 -2
  683. package/dist/agent/ai-sdk-transport.test.d.ts.map +0 -1
  684. package/dist/agent/coalesce.test.d.ts +0 -2
  685. package/dist/agent/coalesce.test.d.ts.map +0 -1
  686. package/dist/agent/foreign.test.d.ts +0 -2
  687. package/dist/agent/foreign.test.d.ts.map +0 -1
  688. package/dist/agent/id.test.d.ts +0 -2
  689. package/dist/agent/id.test.d.ts.map +0 -1
  690. package/dist/agent/merge.test.d.ts +0 -2
  691. package/dist/agent/merge.test.d.ts.map +0 -1
  692. package/dist/agent/part-list.test.d.ts +0 -2
  693. package/dist/agent/part-list.test.d.ts.map +0 -1
  694. package/dist/agent/parts.test.d.ts +0 -2
  695. package/dist/agent/parts.test.d.ts.map +0 -1
  696. package/dist/agent/thread.test.d.ts +0 -2
  697. package/dist/agent/thread.test.d.ts.map +0 -1
  698. package/dist/agent/transport.test.d.ts +0 -2
  699. package/dist/agent/transport.test.d.ts.map +0 -1
  700. package/dist/agent/use-agent-stream.test.d.ts +0 -2
  701. package/dist/agent/use-agent-stream.test.d.ts.map +0 -1
  702. package/dist/agent/use-agent-thread-runs.foreign.test.d.ts +0 -2
  703. package/dist/agent/use-agent-thread-runs.foreign.test.d.ts.map +0 -1
  704. package/dist/agent/use-agent-thread-runs.resume.test.d.ts +0 -2
  705. package/dist/agent/use-agent-thread-runs.resume.test.d.ts.map +0 -1
  706. package/dist/agent/use-agent-thread-runs.test.d.ts +0 -2
  707. package/dist/agent/use-agent-thread-runs.test.d.ts.map +0 -1
  708. package/dist/agent/use-agent-thread-runs.wedge.test.d.ts +0 -2
  709. package/dist/agent/use-agent-thread-runs.wedge.test.d.ts.map +0 -1
  710. package/dist/agent-chat/composer.test.d.ts +0 -2
  711. package/dist/agent-chat/composer.test.d.ts.map +0 -1
  712. package/dist/agent-chat/relative-time.test.d.ts +0 -2
  713. package/dist/agent-chat/relative-time.test.d.ts.map +0 -1
  714. package/dist/agent-chat/thread-feed-row.test.d.ts +0 -2
  715. package/dist/agent-chat/thread-feed-row.test.d.ts.map +0 -1
  716. package/dist/agent-chat/thread-feed.test.d.ts +0 -2
  717. package/dist/agent-chat/thread-feed.test.d.ts.map +0 -1
  718. package/dist/agent-chat/thread-message.test.d.ts +0 -2
  719. package/dist/agent-chat/thread-message.test.d.ts.map +0 -1
  720. package/dist/agent-chat/thread-workspace.test.d.ts +0 -2
  721. package/dist/agent-chat/thread-workspace.test.d.ts.map +0 -1
  722. package/dist/agent-chat/tool-chip.test.d.ts +0 -2
  723. package/dist/agent-chat/tool-chip.test.d.ts.map +0 -1
  724. package/dist/agent-chat/virtualize.type-guard.test.d.ts +0 -2
  725. package/dist/agent-chat/virtualize.type-guard.test.d.ts.map +0 -1
  726. package/dist/charts/cursor/resolve.test.d.ts +0 -2
  727. package/dist/charts/cursor/resolve.test.d.ts.map +0 -1
  728. package/dist/charts/cursor/store.test.d.ts +0 -2
  729. package/dist/charts/cursor/store.test.d.ts.map +0 -1
  730. package/dist/charts/kinds/BandStrip.test.d.ts +0 -2
  731. package/dist/charts/kinds/BandStrip.test.d.ts.map +0 -1
  732. package/dist/charts/kinds/Bars.test.d.ts +0 -2
  733. package/dist/charts/kinds/Bars.test.d.ts.map +0 -1
  734. package/dist/charts/kinds/DualPanel.test.d.ts +0 -2
  735. package/dist/charts/kinds/DualPanel.test.d.ts.map +0 -1
  736. package/dist/charts/kinds/MirroredBars.test.d.ts +0 -2
  737. package/dist/charts/kinds/MirroredBars.test.d.ts.map +0 -1
  738. package/dist/charts/kinds/MultiLine.test.d.ts +0 -2
  739. package/dist/charts/kinds/MultiLine.test.d.ts.map +0 -1
  740. package/dist/charts/kinds/StackedArea.test.d.ts +0 -2
  741. package/dist/charts/kinds/StackedArea.test.d.ts.map +0 -1
  742. package/dist/charts/kinds/ZonedLine.test.d.ts +0 -2
  743. package/dist/charts/kinds/ZonedLine.test.d.ts.map +0 -1
  744. package/dist/charts/layout/auto-margin.test.d.ts +0 -2
  745. package/dist/charts/layout/auto-margin.test.d.ts.map +0 -1
  746. package/dist/charts/primitives/CartesianChart.test.d.ts +0 -2
  747. package/dist/charts/primitives/CartesianChart.test.d.ts.map +0 -1
  748. package/dist/charts/primitives/ChartCard.test.d.ts +0 -2
  749. package/dist/charts/primitives/ChartCard.test.d.ts.map +0 -1
  750. package/dist/charts/primitives/ChartFrame.test.d.ts +0 -2
  751. package/dist/charts/primitives/ChartFrame.test.d.ts.map +0 -1
  752. package/dist/charts/primitives/ChartLegend.test.d.ts +0 -2
  753. package/dist/charts/primitives/ChartLegend.test.d.ts.map +0 -1
  754. package/dist/charts/primitives/ChartTooltip.test.d.ts +0 -2
  755. package/dist/charts/primitives/ChartTooltip.test.d.ts.map +0 -1
  756. package/dist/charts/primitives/XZoneRects.test.d.ts +0 -2
  757. package/dist/charts/primitives/XZoneRects.test.d.ts.map +0 -1
  758. package/dist/charts/series.test.d.ts +0 -2
  759. package/dist/charts/series.test.d.ts.map +0 -1
  760. package/dist/charts/utils/domain.test.d.ts +0 -2
  761. package/dist/charts/utils/domain.test.d.ts.map +0 -1
  762. package/dist/charts/utils/measure-text.test.d.ts +0 -2
  763. package/dist/charts/utils/measure-text.test.d.ts.map +0 -1
  764. package/dist/cli/check-coverage.test.d.ts +0 -2
  765. package/dist/cli/check-coverage.test.d.ts.map +0 -1
  766. package/dist/cli/check-theme.test.d.ts +0 -2
  767. package/dist/cli/check-theme.test.d.ts.map +0 -1
  768. package/dist/cli/help.test.d.ts +0 -2
  769. package/dist/cli/help.test.d.ts.map +0 -1
  770. package/dist/cli/init-sync.test.d.ts +0 -2
  771. package/dist/cli/init-sync.test.d.ts.map +0 -1
  772. package/dist/cli/placement-engine.test.d.ts +0 -2
  773. package/dist/cli/placement-engine.test.d.ts.map +0 -1
  774. package/dist/cli/shipped-versions.test.d.ts +0 -2
  775. package/dist/cli/shipped-versions.test.d.ts.map +0 -1
  776. package/dist/cli/tarball-parity.test.d.ts +0 -2
  777. package/dist/cli/tarball-parity.test.d.ts.map +0 -1
  778. package/dist/cli/template-format.test.d.ts +0 -2
  779. package/dist/cli/template-format.test.d.ts.map +0 -1
  780. package/dist/cli/template-ledger.test.d.ts +0 -2
  781. package/dist/cli/template-ledger.test.d.ts.map +0 -1
  782. package/dist/cli/tokens-css.test.d.ts +0 -2
  783. package/dist/cli/tokens-css.test.d.ts.map +0 -1
  784. package/dist/cli/toolchain-wiring.test.d.ts +0 -2
  785. package/dist/cli/toolchain-wiring.test.d.ts.map +0 -1
  786. package/dist/cli/waiver-audit.test.d.ts +0 -2
  787. package/dist/cli/waiver-audit.test.d.ts.map +0 -1
  788. package/dist/content/article-actions.test.d.ts +0 -2
  789. package/dist/content/article-actions.test.d.ts.map +0 -1
  790. package/dist/content/article-model.test.d.ts +0 -2
  791. package/dist/content/article-model.test.d.ts.map +0 -1
  792. package/dist/content/block-split.test.d.ts +0 -2
  793. package/dist/content/block-split.test.d.ts.map +0 -1
  794. package/dist/content/heading-components.test.d.ts +0 -2
  795. package/dist/content/heading-components.test.d.ts.map +0 -1
  796. package/dist/content/markdown.test.d.ts +0 -2
  797. package/dist/content/markdown.test.d.ts.map +0 -1
  798. package/dist/content/prose.module.css.test.d.ts +0 -2
  799. package/dist/content/prose.module.css.test.d.ts.map +0 -1
  800. package/dist/content/sanitize.test.d.ts +0 -2
  801. package/dist/content/sanitize.test.d.ts.map +0 -1
  802. package/dist/content/slug.test.d.ts +0 -2
  803. package/dist/content/slug.test.d.ts.map +0 -1
  804. package/dist/controls/actions.test.d.ts +0 -2
  805. package/dist/controls/actions.test.d.ts.map +0 -1
  806. package/dist/controls/actions.type-guard.test.d.ts +0 -2
  807. package/dist/controls/actions.type-guard.test.d.ts.map +0 -1
  808. package/dist/controls/control-group.test.d.ts +0 -2
  809. package/dist/controls/control-group.test.d.ts.map +0 -1
  810. package/dist/controls/controls.router.test.d.ts +0 -2
  811. package/dist/controls/controls.router.test.d.ts.map +0 -1
  812. package/dist/controls/filter-set.test.d.ts +0 -2
  813. package/dist/controls/filter-set.test.d.ts.map +0 -1
  814. package/dist/controls/peer-boundary.test.d.ts +0 -2
  815. package/dist/controls/peer-boundary.test.d.ts.map +0 -1
  816. package/dist/controls/props-contract.test.d.ts +0 -2
  817. package/dist/controls/props-contract.test.d.ts.map +0 -1
  818. package/dist/controls/range-filter.type-guard.test.d.ts +0 -2
  819. package/dist/controls/range-filter.type-guard.test.d.ts.map +0 -1
  820. package/dist/controls/sync-button.test.d.ts +0 -2
  821. package/dist/controls/sync-button.test.d.ts.map +0 -1
  822. package/dist/dashboard/query-state.test.d.ts +0 -2
  823. package/dist/dashboard/query-state.test.d.ts.map +0 -1
  824. package/dist/dashboard/settings-section.test.d.ts +0 -2
  825. package/dist/dashboard/settings-section.test.d.ts.map +0 -1
  826. package/dist/dashboard/stat-card.test.d.ts +0 -2
  827. package/dist/dashboard/stat-card.test.d.ts.map +0 -1
  828. package/dist/data/data-table.test.d.ts +0 -2
  829. package/dist/data/data-table.test.d.ts.map +0 -1
  830. package/dist/guard/check-source.test.d.ts +0 -2
  831. package/dist/guard/check-source.test.d.ts.map +0 -1
  832. package/dist/guard/grace.test.d.ts +0 -20
  833. package/dist/guard/grace.test.d.ts.map +0 -1
  834. package/dist/guard/guard-hook.test.d.ts +0 -2
  835. package/dist/guard/guard-hook.test.d.ts.map +0 -1
  836. package/dist/provider/index.test.d.ts +0 -2
  837. package/dist/provider/index.test.d.ts.map +0 -1
  838. package/dist/provider/lab-theme.test.d.ts +0 -2
  839. package/dist/provider/lab-theme.test.d.ts.map +0 -1
  840. package/dist/query/error-message.test.d.ts +0 -2
  841. package/dist/query/error-message.test.d.ts.map +0 -1
  842. package/dist/router-tanstack/multi-search-param-store.test.d.ts +0 -2
  843. package/dist/router-tanstack/multi-search-param-store.test.d.ts.map +0 -1
  844. package/dist/router-tanstack/nav.test.d.ts +0 -2
  845. package/dist/router-tanstack/nav.test.d.ts.map +0 -1
  846. package/dist/router-tanstack/search-param-store.test.d.ts +0 -2
  847. package/dist/router-tanstack/search-param-store.test.d.ts.map +0 -1
  848. package/dist/router-tanstack/search-store.router.test.d.ts +0 -2
  849. package/dist/router-tanstack/search-store.router.test.d.ts.map +0 -1
  850. package/dist/router-tanstack/search-store.test.d.ts +0 -2
  851. package/dist/router-tanstack/search-store.test.d.ts.map +0 -1
  852. package/dist/router-tanstack/use-nav.test.d.ts +0 -2
  853. package/dist/router-tanstack/use-nav.test.d.ts.map +0 -1
  854. package/dist/section/section.test.d.ts +0 -2
  855. package/dist/section/section.test.d.ts.map +0 -1
  856. package/dist/shell/app-mobile-nav.test.d.ts +0 -2
  857. package/dist/shell/app-mobile-nav.test.d.ts.map +0 -1
  858. package/dist/shell/app-sidebar.test.d.ts +0 -2
  859. package/dist/shell/app-sidebar.test.d.ts.map +0 -1
  860. package/dist/shell/index.test.d.ts +0 -2
  861. package/dist/shell/index.test.d.ts.map +0 -1
  862. package/dist/shell/mobile-nav-model.test.d.ts +0 -2
  863. package/dist/shell/mobile-nav-model.test.d.ts.map +0 -1
  864. package/dist/shell/page-bar.test.d.ts +0 -2
  865. package/dist/shell/page-bar.test.d.ts.map +0 -1
  866. package/dist/state/fields.test.d.ts +0 -2
  867. package/dist/state/fields.test.d.ts.map +0 -1
  868. package/dist/state/persisted.test.d.ts +0 -2
  869. package/dist/state/persisted.test.d.ts.map +0 -1
  870. package/dist/styles.floor.test.d.ts +0 -2
  871. package/dist/styles.floor.test.d.ts.map +0 -1
  872. package/dist/theme/border-coverage.test.d.ts +0 -18
  873. package/dist/theme/border-coverage.test.d.ts.map +0 -1
  874. package/dist/theme/contrast.test.d.ts +0 -2
  875. package/dist/theme/contrast.test.d.ts.map +0 -1
  876. package/dist/theme/ctl-theme.test.d.ts +0 -2
  877. package/dist/theme/ctl-theme.test.d.ts.map +0 -1
  878. package/dist/theme/ctl-tier-coverage.test.d.ts +0 -2
  879. package/dist/theme/ctl-tier-coverage.test.d.ts.map +0 -1
  880. package/dist/theme/density-option.test.d.ts +0 -2
  881. package/dist/theme/density-option.test.d.ts.map +0 -1
  882. package/dist/theme/density-relations.test.d.ts +0 -2
  883. package/dist/theme/density-relations.test.d.ts.map +0 -1
  884. package/dist/theme/derive-theme.test.d.ts +0 -2
  885. package/dist/theme/derive-theme.test.d.ts.map +0 -1
  886. package/dist/theme/divider-law.test.d.ts +0 -2
  887. package/dist/theme/divider-law.test.d.ts.map +0 -1
  888. package/dist/theme/fonts-option.test.d.ts +0 -2
  889. package/dist/theme/fonts-option.test.d.ts.map +0 -1
  890. package/dist/theme/icon-slot.test.d.ts +0 -2
  891. package/dist/theme/icon-slot.test.d.ts.map +0 -1
  892. package/dist/theme/layout-rhythm-css.test.d.ts +0 -2
  893. package/dist/theme/layout-rhythm-css.test.d.ts.map +0 -1
  894. package/dist/theme/radius-option.test.d.ts +0 -2
  895. package/dist/theme/radius-option.test.d.ts.map +0 -1
  896. package/dist/theme/radius.test.d.ts +0 -2
  897. package/dist/theme/radius.test.d.ts.map +0 -1
  898. package/dist/theme/shadow-surfaces.test.d.ts +0 -26
  899. package/dist/theme/shadow-surfaces.test.d.ts.map +0 -1
  900. package/dist/theme/spacing.test.d.ts +0 -2
  901. package/dist/theme/spacing.test.d.ts.map +0 -1
  902. package/dist/theme/use-basalt-spacing.test.d.ts +0 -2
  903. package/dist/theme/use-basalt-spacing.test.d.ts.map +0 -1
  904. package/dist/theme-lab/derive-controls.test.d.ts +0 -2
  905. package/dist/theme-lab/derive-controls.test.d.ts.map +0 -1
  906. package/dist/theme-lab/derive-state.test.d.ts +0 -2
  907. package/dist/theme-lab/derive-state.test.d.ts.map +0 -1
  908. package/dist/theme-lab/theme-lab.test.d.ts +0 -2
  909. package/dist/theme-lab/theme-lab.test.d.ts.map +0 -1
  910. package/dist/tokens/build-fonts-css.test.d.ts +0 -2
  911. package/dist/tokens/build-fonts-css.test.d.ts.map +0 -1
  912. package/dist/tokens/build-radius-css.test.d.ts +0 -2
  913. package/dist/tokens/build-radius-css.test.d.ts.map +0 -1
  914. package/dist/tokens/chart-margin.test.d.ts +0 -2
  915. package/dist/tokens/chart-margin.test.d.ts.map +0 -1
  916. package/dist/tokens/density.test.d.ts +0 -2
  917. package/dist/tokens/density.test.d.ts.map +0 -1
  918. package/dist/tokens/derive-radius.test.d.ts +0 -2
  919. package/dist/tokens/derive-radius.test.d.ts.map +0 -1
  920. package/dist/tokens/derive.test.d.ts +0 -2
  921. package/dist/tokens/derive.test.d.ts.map +0 -1
  922. package/dist/tokens/palette.test.d.ts +0 -2
  923. package/dist/tokens/palette.test.d.ts.map +0 -1
  924. package/dist/tokens/text-scale.test.d.ts +0 -2
  925. package/dist/tokens/text-scale.test.d.ts.map +0 -1
  926. package/dist/vite-color-mix.test.d.ts +0 -2
  927. package/dist/vite-color-mix.test.d.ts.map +0 -1
  928. package/dist/vite.test.d.ts +0 -2
  929. package/dist/vite.test.d.ts.map +0 -1
  930. package/dist/widget-header/delta-badge.test.d.ts +0 -2
  931. package/dist/widget-header/delta-badge.test.d.ts.map +0 -1
  932. package/dist/widget-header/no-mantine.test.d.ts +0 -2
  933. package/dist/widget-header/no-mantine.test.d.ts.map +0 -1
  934. package/dist/widget-header/widget-header.test.d.ts +0 -2
  935. package/dist/widget-header/widget-header.test.d.ts.map +0 -1
  936. package/src/agent/adapter.test.ts +0 -1640
  937. package/src/agent/ai-sdk-transport.test.ts +0 -658
  938. package/src/agent/coalesce.test.ts +0 -387
  939. package/src/agent/foreign.test.ts +0 -51
  940. package/src/agent/id.test.ts +0 -169
  941. package/src/agent/merge.test.ts +0 -206
  942. package/src/agent/part-list.test.tsx +0 -112
  943. package/src/agent/parts.test.ts +0 -720
  944. package/src/agent/thread.test.ts +0 -220
  945. package/src/agent/transport.test.ts +0 -70
  946. package/src/agent/use-agent-stream.test.tsx +0 -287
  947. package/src/agent/use-agent-thread-runs.foreign.test.tsx +0 -138
  948. package/src/agent/use-agent-thread-runs.resume.test.tsx +0 -294
  949. package/src/agent/use-agent-thread-runs.test.tsx +0 -1120
  950. package/src/agent/use-agent-thread-runs.wedge.test.tsx +0 -387
  951. package/src/agent-chat/composer.test.tsx +0 -924
  952. package/src/agent-chat/relative-time.test.ts +0 -95
  953. package/src/agent-chat/thread-feed-row.test.tsx +0 -510
  954. package/src/agent-chat/thread-feed.test.tsx +0 -241
  955. package/src/agent-chat/thread-message.test.tsx +0 -1285
  956. package/src/agent-chat/thread-workspace.test.tsx +0 -169
  957. package/src/agent-chat/tool-chip.test.tsx +0 -139
  958. package/src/agent-chat/virtualize.type-guard.test.ts +0 -49
  959. package/src/charts/cursor/resolve.test.ts +0 -151
  960. package/src/charts/cursor/store.test.ts +0 -64
  961. package/src/charts/kinds/BandStrip.test.tsx +0 -282
  962. package/src/charts/kinds/Bars.test.tsx +0 -183
  963. package/src/charts/kinds/DualPanel.test.tsx +0 -527
  964. package/src/charts/kinds/MirroredBars.test.tsx +0 -232
  965. package/src/charts/kinds/MultiLine.test.tsx +0 -218
  966. package/src/charts/kinds/StackedArea.test.tsx +0 -114
  967. package/src/charts/kinds/ZonedLine.test.tsx +0 -147
  968. package/src/charts/layout/auto-margin.test.ts +0 -42
  969. package/src/charts/primitives/CartesianChart.test.tsx +0 -647
  970. package/src/charts/primitives/ChartCard.test.tsx +0 -66
  971. package/src/charts/primitives/ChartFrame.test.tsx +0 -142
  972. package/src/charts/primitives/ChartLegend.test.tsx +0 -78
  973. package/src/charts/primitives/ChartTooltip.test.tsx +0 -44
  974. package/src/charts/primitives/XZoneRects.test.tsx +0 -123
  975. package/src/charts/series.test.ts +0 -112
  976. package/src/charts/utils/domain.test.ts +0 -54
  977. package/src/charts/utils/measure-text.test.ts +0 -36
  978. package/src/cli/check-coverage.test.ts +0 -297
  979. package/src/cli/check-theme.test.ts +0 -837
  980. package/src/cli/help.test.ts +0 -170
  981. package/src/cli/init-sync.test.ts +0 -343
  982. package/src/cli/placement-engine.test.ts +0 -298
  983. package/src/cli/shipped-versions.test.ts +0 -83
  984. package/src/cli/tarball-parity.test.ts +0 -44
  985. package/src/cli/template-format.test.ts +0 -64
  986. package/src/cli/template-ledger.test.ts +0 -219
  987. package/src/cli/tokens-css.test.ts +0 -249
  988. package/src/cli/toolchain-wiring.test.ts +0 -1358
  989. package/src/cli/waiver-audit.test.ts +0 -215
  990. package/src/content/article-actions.test.ts +0 -78
  991. package/src/content/article-model.test.ts +0 -119
  992. package/src/content/block-split.test.ts +0 -75
  993. package/src/content/heading-components.test.tsx +0 -65
  994. package/src/content/markdown.test.tsx +0 -603
  995. package/src/content/prose.module.css.test.ts +0 -39
  996. package/src/content/sanitize.test.ts +0 -659
  997. package/src/content/slug.test.ts +0 -62
  998. package/src/controls/actions.test.tsx +0 -252
  999. package/src/controls/actions.type-guard.test.ts +0 -63
  1000. package/src/controls/control-group.test.tsx +0 -229
  1001. package/src/controls/controls.router.test.tsx +0 -1053
  1002. package/src/controls/filter-set.test.tsx +0 -472
  1003. package/src/controls/peer-boundary.test.ts +0 -85
  1004. package/src/controls/props-contract.test.tsx +0 -137
  1005. package/src/controls/range-filter.type-guard.test.tsx +0 -122
  1006. package/src/controls/sync-button.test.tsx +0 -183
  1007. package/src/dashboard/query-state.test.tsx +0 -152
  1008. package/src/dashboard/settings-section.test.tsx +0 -56
  1009. package/src/dashboard/stat-card.test.tsx +0 -385
  1010. package/src/data/data-table.test.tsx +0 -434
  1011. package/src/guard/check-source.test.ts +0 -3388
  1012. package/src/guard/grace.test.ts +0 -158
  1013. package/src/guard/guard-hook.test.ts +0 -203
  1014. package/src/provider/index.test.tsx +0 -101
  1015. package/src/provider/lab-theme.test.ts +0 -147
  1016. package/src/query/error-message.test.ts +0 -67
  1017. package/src/router-tanstack/multi-search-param-store.test.ts +0 -124
  1018. package/src/router-tanstack/nav.test.ts +0 -111
  1019. package/src/router-tanstack/search-param-store.test.ts +0 -135
  1020. package/src/router-tanstack/search-store.router.test.tsx +0 -882
  1021. package/src/router-tanstack/search-store.test.ts +0 -578
  1022. package/src/router-tanstack/use-nav.test.tsx +0 -187
  1023. package/src/section/section.test.tsx +0 -204
  1024. package/src/shell/app-mobile-nav.test.tsx +0 -403
  1025. package/src/shell/app-sidebar.test.tsx +0 -509
  1026. package/src/shell/index.test.tsx +0 -428
  1027. package/src/shell/mobile-nav-model.test.ts +0 -517
  1028. package/src/shell/page-bar.test.tsx +0 -316
  1029. package/src/state/fields.test.tsx +0 -512
  1030. package/src/state/persisted.test.ts +0 -91
  1031. package/src/styles.floor.test.ts +0 -36
  1032. package/src/theme/border-coverage.test.ts +0 -272
  1033. package/src/theme/contrast.test.ts +0 -354
  1034. package/src/theme/ctl-theme.test.tsx +0 -275
  1035. package/src/theme/ctl-tier-coverage.test.ts +0 -170
  1036. package/src/theme/density-option.test.ts +0 -96
  1037. package/src/theme/density-relations.test.ts +0 -506
  1038. package/src/theme/derive-theme.test.ts +0 -101
  1039. package/src/theme/divider-law.test.ts +0 -259
  1040. package/src/theme/fonts-option.test.ts +0 -75
  1041. package/src/theme/icon-slot.test.tsx +0 -275
  1042. package/src/theme/layout-rhythm-css.test.ts +0 -72
  1043. package/src/theme/radius-option.test.ts +0 -86
  1044. package/src/theme/radius.test.ts +0 -142
  1045. package/src/theme/shadow-surfaces.test.ts +0 -488
  1046. package/src/theme/spacing.test.ts +0 -495
  1047. package/src/theme/use-basalt-spacing.test.tsx +0 -55
  1048. package/src/theme-lab/derive-controls.test.ts +0 -94
  1049. package/src/theme-lab/derive-state.test.ts +0 -71
  1050. package/src/theme-lab/theme-lab.test.ts +0 -46
  1051. package/src/tokens/build-fonts-css.test.ts +0 -52
  1052. package/src/tokens/build-radius-css.test.ts +0 -25
  1053. package/src/tokens/chart-margin.test.ts +0 -39
  1054. package/src/tokens/density.test.ts +0 -259
  1055. package/src/tokens/derive-radius.test.ts +0 -62
  1056. package/src/tokens/derive.test.ts +0 -30
  1057. package/src/tokens/palette.test.ts +0 -114
  1058. package/src/tokens/text-scale.test.ts +0 -51
  1059. package/src/vite-color-mix.test.ts +0 -46
  1060. package/src/vite.test.ts +0 -423
  1061. package/src/widget-header/delta-badge.test.tsx +0 -60
  1062. package/src/widget-header/no-mantine.test.ts +0 -33
  1063. package/src/widget-header/widget-header.test.tsx +0 -187
@@ -1,6 +1,9 @@
1
1
  /**
2
2
  * Section — the tier-2 heading composer (docs/CONTROLS-SPEC.md §2.2, law C8): a page-level content
3
- * grouping under `WidgetHeader tier="section"`. Named exactly `Section` — not `PageSection` — so
3
+ * grouping under `WidgetHeader tier="section"` — or `tier="group"` when the section renders on the
4
+ * `PageAside` panel surface, resolved from `useFilterSurface()` and never a call-site prop (law C1:
5
+ * no fourth home, no new prop — the aside decides, not the caller). Named exactly `Section` — not
6
+ * `PageSection` — so
4
7
  * the existing `shadow-basalt-export` guard fires on a consumer's own hand-rolled `Section` /
5
8
  * `PageSection` / `SectionTitle` / `SectionHeading` copy with zero new rule code.
6
9
  *
@@ -9,8 +12,8 @@
9
12
  *
10
13
  * `actions` and `tabs` are two separate `CtlSlot`-wrapped fragments rendered in the header row
11
14
  * (C1/C5) via `WidgetHeader`'s single `actions` slot; `tabs` hides while the section is collapsed.
12
- * `Section` holds ≤3 actions (C6) — past that, a dev-only console warning fires (the AST guard
13
- * lands in wave 6).
15
+ * `Section` holds ≤3 actions (C6) — past that, a dev-only `useValidateProps` message fires once per
16
+ * title (the AST guard lands in wave 6).
14
17
  *
15
18
  * `collapsible` state persists via `createPersistedState('basalt:section:<persistKey>')` when
16
19
  * `persistKey` is given, else it is local `useState` — the header always stays drawn, only the body
@@ -43,77 +46,101 @@
43
46
  * <UsageChart />
44
47
  * </Section>
45
48
  */
46
- import { Children, useId, useMemo, useState } from 'react'
49
+ import { Children, useId } from 'react'
47
50
  import type { ReactNode } from 'react'
51
+ import { cx } from '../common/props'
52
+ import type { BasaltProps, SlotStylesProps } from '../common/props'
53
+ import { BASALT_PREFIX } from '../common/errors'
54
+ import { useValidateProps } from '../common/validate'
48
55
  import { CtlSlot } from '../theme'
49
- import { createPersistedState } from '../state'
56
+ import { BarActionSlot, isBarActionList } from '../controls/actions'
57
+ import type { SlotActions } from '../controls/actions'
58
+ import { useFilterSurface } from '../controls/filter-context'
59
+ import { QueryState } from '../dashboard/query-state'
60
+ import type { QueryEmptyCopy, QueryStateLike } from '../dashboard/query-state'
61
+ import { usePersistedOrLocal } from '../state/persisted-or-local'
50
62
  import { WidgetHeader } from '../widget-header'
51
63
  import type { WidgetHeaderProps } from '../widget-header'
52
64
  import classes from './section.module.css'
53
65
 
54
- export type SectionProps = Omit<WidgetHeaderProps, 'tier'> & {
55
- /** Rendered in the header row, in its own `CtlSlot` — hidden while the section is collapsed. */
56
- tabs?: ReactNode
57
- /** Renders a chevron toggle in the header; the header stays drawn when closed, only `children`
58
- * (and `tabs`) unmount. @default false */
59
- collapsible?: boolean
60
- /** Persists the fold state at `basalt:section:<persistKey>`. Omit for a local, unpersisted fold
61
- * (`useState`). */
62
- persistKey?: string
63
- /** The fold state a section opens on, respected only while no persisted value exists — a section
64
- * a reader has closed stays closed. `false` is what a long secondary block wants. @default true */
65
- defaultOpen?: boolean
66
- /** Rendered directly under the header and ALWAYS visible, collapsed or not: a collapsed section
67
- * still states its headline figures, which is what makes collapsing it a real option. Keep it to
68
- * one row — the body is what `children` is for. */
69
- summary?: ReactNode
70
- /** Turns the root into a scroll anchor (`id` + `scroll-margin-top` cleared for both sticky bars). */
71
- id?: string
72
- children: ReactNode
73
- }
74
-
75
- /** The house dev gate (`data/data-table.tsx`, `provider`, `charts/kinds/BandStrip` use the same
76
- * expression): `basaltViteConfig` defines `process.env.NODE_ENV`, so a production bundle
77
- * constant-folds this to `false` and drops the warning. Read per call, never hoisted. */
78
- function isDev(): boolean {
79
- return process.env['NODE_ENV'] !== 'production'
80
- }
81
-
82
- /** ≤3 actions is C6 (docs/CONTROLS-SPEC.md §1) — the AST guard (`basalt/page-bar-budget`) lands in
83
- * wave 6; this is the dev-only stopgap so the budget is visible before the lint rule exists. */
84
- function warnPastActionBudget(title: string, actions: ReactNode): void {
85
- if (!isDev()) return
86
- const count = Children.count(actions)
87
- if (count <= 3) return
88
- console.warn(
89
- `Section "${title}": ${count} actions exceeds the ≤3 budget (docs/CONTROLS-SPEC.md C6) — ` +
90
- 'move the rest behind a menu.',
91
- )
92
- }
66
+ /**
67
+ * The three boxes `Section` paints, and the whole styling seam it offers (`common/props.ts`):
68
+ * `root` is the outer stack, `header` is the `WidgetHeader` row, `body` is the collapsible content
69
+ * box. `summary` is deliberately absent — it is a one-row readout under the header, not a layout
70
+ * box a consumer positions.
71
+ */
72
+ export type SectionSlot = 'root' | 'header' | 'body'
93
73
 
94
- const UNPERSISTED_KEY = '__local__'
74
+ // `classNames` is omitted alongside `tier`: `WidgetHeader` publishes its OWN slot union now, and
75
+ // intersecting the two would let a caller write `classNames={{ metric: … }}` on a `Section` and get
76
+ // silence. Section's three slots are its whole styling contract; the header's own slots are reached
77
+ // on a `WidgetHeader`.
78
+ export type SectionProps = Omit<WidgetHeaderProps, 'tier' | 'classNames' | 'actions'> &
79
+ BasaltProps &
80
+ SlotStylesProps<SectionSlot> & {
81
+ /**
82
+ * Header actions, in either form (law C15): a typed `BarAction[]`, which basalt projects through
83
+ * the SAME row `PageBar` and `ActionGroup` use — ≤3 inline, the rest folded into `More`, one
84
+ * kebab below `sm` — or an opaque `ReactNode` a caller drew itself, rendered verbatim. The ≤3
85
+ * budget (C6) is checked against whichever form is given.
86
+ */
87
+ actions?: SlotActions
88
+ /**
89
+ * The section's async result. Given one, the BODY renders through `QueryState` at the section
90
+ * tier — pending / error-with-retry / empty each REPLACE `children`, data renders them — while
91
+ * the header, the fold chevron and `summary` stay drawn throughout, so a section never blinks out
92
+ * of the page while it refetches.
93
+ *
94
+ * This is law C3's uniform container contract (`docs/CONTROLS-SPEC.md` §1): without it every
95
+ * caller re-derives the four-way switch `QueryState` exists to delete, and gets it wrong in the
96
+ * one direction that matters — "nothing here" printed over a 500.
97
+ */
98
+ query?: QueryStateLike<unknown>
99
+ /**
100
+ * Copy for `query`'s EMPTY branch, rendered through `EmptyState` like every other one. Omit to
101
+ * render nothing when the result is empty — `QueryState`'s own contract, unchanged. Ignored
102
+ * without `query`.
103
+ */
104
+ empty?: QueryEmptyCopy
105
+ /** Rendered in the header row, in its own `CtlSlot` — hidden while the section is collapsed. */
106
+ tabs?: ReactNode
107
+ /** Renders a chevron toggle in the header; the header stays drawn when closed, only `children`
108
+ * (and `tabs`) unmount. @default false */
109
+ collapsible?: boolean
110
+ /** Persists the fold state at `basalt:section:<persistKey>`. Omit for a local, unpersisted fold
111
+ * (`useState`). */
112
+ persistKey?: string
113
+ /** The fold state a section opens on, respected only while no persisted value exists — a section
114
+ * a reader has closed stays closed. `false` is what a long secondary block wants. @default true */
115
+ defaultOpen?: boolean
116
+ /** Rendered directly under the header and ALWAYS visible, collapsed or not: a collapsed section
117
+ * still states its headline figures, which is what makes collapsing it a real option. Keep it to
118
+ * one row — the body is what `children` is for. */
119
+ summary?: ReactNode
120
+ /** Turns the root into a scroll anchor (`id` + `scroll-margin-top` cleared for both sticky bars). */
121
+ id?: string
122
+ children: ReactNode
123
+ }
95
124
 
96
- /** Collapse state — `createPersistedState` when `persistKey` is given, else local `useState`.
97
- * Both hooks are always called (stable order across renders); only the unpersisted branch's setter
98
- * is ever invoked when `persistKey` is absent, so no unpersisted Section writes to storage. */
99
- function useSectionOpen(
100
- persistKey: string | undefined,
101
- defaultOpen: boolean,
102
- ): readonly [boolean, (next: boolean) => void] {
103
- const [localOpen, setLocalOpen] = useState(defaultOpen)
104
- const usePersistedOpen = useMemo(
105
- () =>
106
- createPersistedState<boolean>({
107
- key: `section:${persistKey ?? UNPERSISTED_KEY}`,
108
- version: 1,
109
- initial: defaultOpen,
110
- }),
111
- [persistKey, defaultOpen],
125
+ /**
126
+ * ≤3 actions is C6 (docs/CONTROLS-SPEC.md §1) — the AST guard (`basalt/page-bar-budget`) lands in
127
+ * wave 6; this is the dev-only stopgap so the budget is visible before the lint rule exists.
128
+ *
129
+ * Returns the message rather than logging it, because it is a {@link useValidateProps} check now:
130
+ * it used to `console.warn` straight from the render body, which said it again on every keystroke
131
+ * that re-rendered the page. The title is IN the message on purpose — the dedup key is
132
+ * `${component} ${message}`, so two over-budget sections only both get heard because they name
133
+ * themselves.
134
+ */
135
+ function actionBudgetMessage(title: string, actions: SlotActions): string | null {
136
+ // Both arms of the union are counted, and the typed one is counted EXACTLY: `Children.count` over
137
+ // a `BarAction[]` would report the array's length as one child.
138
+ const count = isBarActionList(actions) ? actions.length : Children.count(actions)
139
+ if (count <= 3) return null
140
+ return (
141
+ `${BASALT_PREFIX} Section "${title}": ${count} actions exceeds the ≤3 budget ` +
142
+ '(docs/CONTROLS-SPEC.md C6) — move the rest behind a menu.'
112
143
  )
113
- const [persistedOpen, setPersistedOpen] = usePersistedOpen()
114
-
115
- if (persistKey !== undefined) return [persistedOpen, setPersistedOpen] as const
116
- return [localOpen, setLocalOpen] as const
117
144
  }
118
145
 
119
146
  function ChevronToggle({
@@ -151,16 +178,9 @@ function ChevronToggle({
151
178
  }
152
179
 
153
180
  export function Section({
154
- title,
155
- icon,
156
- subtitle,
157
- info,
158
- value,
159
- delta,
160
- deltaPeriod,
161
- sparkline,
162
- count,
163
181
  actions,
182
+ query,
183
+ empty,
164
184
  tabs,
165
185
  collapsible = false,
166
186
  persistKey,
@@ -168,17 +188,66 @@ export function Section({
168
188
  summary,
169
189
  id,
170
190
  children,
191
+ className,
192
+ style,
193
+ classNames,
194
+ ...headerProps
171
195
  }: SectionProps) {
172
- const [open, setOpen] = useSectionOpen(persistKey, defaultOpen)
196
+ const { title } = headerProps
197
+
198
+ // Two dev-only checks, one hook — both are misuses that RENDER fine, which is what puts them in
199
+ // `useValidateProps` rather than in `assertRequiredProps`.
200
+ //
201
+ // 1. A `persistKey` with nothing to fold writes a localStorage key nobody ever reads back — the
202
+ // shape a consumer lands on after deleting `collapsible` and leaving the key behind.
203
+ // 2. More than three header actions (C6). This used to `console.warn` from the render body, so a
204
+ // page that re-rendered on every keystroke reprinted it every keystroke.
205
+ useValidateProps(
206
+ 'Section',
207
+ () => [
208
+ persistKey !== undefined && !collapsible
209
+ ? `${BASALT_PREFIX} Section "${title}": \`persistKey\` is set but \`collapsible\` is ` +
210
+ 'false — there is no fold to persist. Add `collapsible`, or drop `persistKey`.'
211
+ : null,
212
+ actions === undefined ? null : actionBudgetMessage(title, actions),
213
+ ],
214
+ [persistKey, collapsible, title, actions],
215
+ )
216
+
217
+ const [open, setOpen] = usePersistedOrLocal({
218
+ scope: 'section',
219
+ persistKey,
220
+ initial: defaultOpen,
221
+ })
173
222
  const bodyId = useId()
223
+ // The aside decides, not the call site (law C1): a Section on the PageAside panel surface, or on
224
+ // its mobile sheet projection, renders the quiet `group` tier automatically — a Section never
225
+ // lives inside a pill FilterSet fold, so `'pill'` (the context default outside any provider) is
226
+ // the only surface that stays `section`.
227
+ const tier = useFilterSurface() === 'pill' ? 'section' : 'group'
174
228
 
175
- if (actions !== undefined) warnPastActionBudget(title, actions)
229
+ // The anchor offset is Section's own, so the caller's `style` merges OVER it rather than
230
+ // replacing it — a consumer setting a margin must not silently drop the scroll offset.
231
+ //
232
+ // NO chrome height in this offset. An anchor scroll happens inside the SCROLLPORT, and since
233
+ // `AppShell.Main` became that box (`shell/app-main.module.css`) BOTH the app header and `PageBar`
234
+ // row 2's band are shell regions rendered outside it — counting either would land every `#anchor`
235
+ // that far below its own heading. What is left is breathing room, which is exactly what
236
+ // `--vx-space-sticky-header-clearance` means (tokens/palette.ts, `deriveSpacing`).
237
+ const anchorStyle =
238
+ id === undefined ? undefined : { scrollMarginTop: 'var(--vx-space-sticky-header-clearance)' }
239
+ const rootStyle =
240
+ anchorStyle === undefined && style === undefined ? undefined : { ...anchorStyle, ...style }
176
241
 
177
242
  const headerActions =
178
243
  tabs !== undefined || actions !== undefined || collapsible ? (
179
244
  <>
180
245
  {tabs !== undefined && open && <CtlSlot>{tabs}</CtlSlot>}
181
- {actions !== undefined && <CtlSlot>{actions}</CtlSlot>}
246
+ {actions !== undefined && (
247
+ <CtlSlot>
248
+ <BarActionSlot actions={actions} />
249
+ </CtlSlot>
250
+ )}
182
251
  {collapsible && (
183
252
  <ChevronToggle open={open} onToggle={() => setOpen(!open)} controls={bodyId} />
184
253
  )}
@@ -187,32 +256,30 @@ export function Section({
187
256
 
188
257
  return (
189
258
  <div
190
- className={classes.root}
259
+ className={cx(classes.root, classNames?.root, className)}
260
+ data-tier={tier}
191
261
  {...(id !== undefined && { id })}
192
- {...(id !== undefined && {
193
- style: {
194
- scrollMarginTop:
195
- 'calc(var(--app-shell-header-height, 0px) + var(--basalt-page-bar-h, 0px))',
196
- },
197
- })}
262
+ {...(rootStyle !== undefined && { style: rootStyle })}
198
263
  >
199
264
  <WidgetHeader
200
- tier="section"
201
- title={title}
202
- {...(icon !== undefined && { icon })}
203
- {...(subtitle !== undefined && { subtitle })}
204
- {...(info !== undefined && { info })}
205
- {...(value !== undefined && { value })}
206
- {...(delta !== undefined && { delta })}
207
- {...(deltaPeriod !== undefined && { deltaPeriod })}
208
- {...(sparkline !== undefined && { sparkline })}
209
- {...(count !== undefined && { count })}
265
+ tier={tier}
266
+ {...headerProps}
267
+ {...(classNames?.header !== undefined && { className: classNames.header })}
210
268
  {...(headerActions !== undefined && { actions: headerActions })}
211
269
  />
212
270
  {summary !== undefined && <div className={classes.summary}>{summary}</div>}
213
271
  {open && (
214
- <div id={bodyId} className={classes.body}>
215
- {children}
272
+ <div id={bodyId} className={cx(classes.body, classNames?.body)}>
273
+ {query === undefined ? (
274
+ children
275
+ ) : (
276
+ // `tier="section"` is the compact one: a bare spinner rather than a 64px centred
277
+ // block, and the error alert without the page-level stack around it. A Section IS the
278
+ // region, so the state belongs inside its body, never around its header.
279
+ <QueryState query={query} tier="section" {...(empty !== undefined && { empty })}>
280
+ {children}
281
+ </QueryState>
282
+ )}
216
283
  </div>
217
284
  )}
218
285
  </div>
@@ -6,8 +6,11 @@
6
6
  */
7
7
  import type { ReactNode } from 'react'
8
8
 
9
- /** Badge tone for a role/plan chip. No dedicated tone union exists elsewhere in the shell/tokens
10
- * layers, so this is defined locally. */
9
+ /**
10
+ * Badge tone for a role/plan chip. A different member set from `common`'s `Tone` (`common/props.ts`,
11
+ * audit A13) — `'neutral' | 'brand'` have no `Tone` equivalent — so this stays its own type rather
12
+ * than an alias; see `Tone` for the base three-tone vocabulary the rest of the framework shares.
13
+ */
11
14
  export type AccountBadgeTone = 'neutral' | 'brand' | 'success' | 'warn'
12
15
 
13
16
  /** The signed-in user's identity. `image` is nullable and currently unused by `SidebarAccount`
@@ -0,0 +1,109 @@
1
+ /*
2
+ * The header's leading zone (docs/DESIGN-SPEC.md §5). Moved here from `app-sidebar.module.css`
3
+ * verbatim — the brand did not change, only where it is painted.
4
+ *
5
+ * NO border and no background: the zone is part of the header row, so the header's own
6
+ * `AppShell.Header` region seam is the only line under it. The sidebar column below now starts
7
+ * directly with `SidebarSearch`.
8
+ *
9
+ * The zone's WIDTH is `--app-shell-navbar-offset`, so it tracks the rail collapse with no React
10
+ * state and lands its trailing edge exactly on the sidebar|main seam. The negative
11
+ * `margin-inline-start` cancels `AppShell.Header`'s own `px` inset so the zone starts at the
12
+ * viewport edge and re-applies that inset as padding — which is what puts the brand lead on the
13
+ * same x as the sidebar rows below it.
14
+ */
15
+ .zone {
16
+ flex: 0 0 var(--app-shell-navbar-offset, 0rem);
17
+ width: var(--app-shell-navbar-offset, 0rem);
18
+ min-width: 0;
19
+ display: flex;
20
+ align-items: center;
21
+ /* The full header row, not just the toggle's own 28px — so the zone's box is the band it looks
22
+ * like, and the rail's centred toggle centres against the whole row. */
23
+ align-self: stretch;
24
+ margin-inline-start: calc(-1 * var(--app-shell-padding, 0px));
25
+ padding-inline: var(--app-shell-padding, 0px);
26
+ overflow: hidden;
27
+ /* Mantine's own AppShell timing, so the zone and the navbar under it move as one box. */
28
+ transition-property: flex-basis, width;
29
+ transition-duration: var(--app-shell-transition-duration);
30
+ transition-timing-function: var(--app-shell-transition-timing-function);
31
+ }
32
+
33
+ /* Below `sm` there is no navbar at all (the bottom bar is the whole nav), so the zone would be a
34
+ * zero-width box holding a hidden toggle. The breadcrumb owns the phone header's lead. */
35
+ @media (max-width: 47.99375em) {
36
+ .zone {
37
+ display: none;
38
+ }
39
+ }
40
+
41
+ .brand {
42
+ justify-content: space-between;
43
+ align-items: center;
44
+ flex: 1 1 auto;
45
+ min-width: 0;
46
+ height: 100%;
47
+ }
48
+
49
+ .brandLead {
50
+ min-width: 0;
51
+ }
52
+
53
+ /* Brand name — head font at stretch 88% (docs/DESIGN-SPEC.md §3); the 18px/550 land as `fz`/`fw`
54
+ * props (inline, deterministic against Mantine's own Text base rule). */
55
+ .brandName {
56
+ font-family: var(--basalt-font-head);
57
+ font-stretch: 88%;
58
+ }
59
+
60
+ /* Workspace switcher (`brand.menu`) — the brand name plus a chevron, as a row-shaped trigger. The
61
+ * chevron is faint until hover so the brand still reads as the brand, not as a control. */
62
+ .brandButton {
63
+ display: flex;
64
+ align-items: center;
65
+ gap: var(--vx-space-sidebar-section-label-gap);
66
+ min-width: 0;
67
+ padding: 0;
68
+ color: var(--vx-faint);
69
+ cursor: pointer;
70
+ }
71
+
72
+ .brandButton:hover {
73
+ color: var(--vx-ink);
74
+ }
75
+
76
+ /*
77
+ * Icon-only ghost button in shell chrome (the collapse toggle) — docs/DESIGN-SPEC.md §5:
78
+ * transparent, faint icon, hover ink-6% + ink, radius 6. `!important` because it competes with
79
+ * Mantine's own compiled ActionIcon variant CSS. This is the one copy — `sidebar-search.module.css`
80
+ * mirrors it rather than keeping its own duplicate.
81
+ */
82
+ .ghostIcon {
83
+ color: var(--vx-faint) !important;
84
+ border-radius: var(--vx-radius-ctrl) !important;
85
+ }
86
+
87
+ .ghostIcon:hover {
88
+ background-color: color-mix(in srgb, var(--vx-ink) 6%, transparent) !important;
89
+ color: var(--vx-ink) !important;
90
+ }
91
+
92
+ /*
93
+ * The rail form, mirroring exactly what the sidebar's own brand row did when collapsed: the lead
94
+ * (logo + name) hides and the toggle centres. The zone drops its inset so the toggle's centre lands
95
+ * on the rail's icon column rather than 13px right of it.
96
+ */
97
+ @media (min-width: 48em) {
98
+ .zone[data-collapsed] {
99
+ padding-inline: 0;
100
+ }
101
+
102
+ .zone[data-collapsed] .brand {
103
+ justify-content: center;
104
+ }
105
+
106
+ .zone[data-collapsed] .brandLead {
107
+ display: none;
108
+ }
109
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Typed CSS-module declaration (the S4 CSS-modules path). Named string props — not an index
3
+ * signature — so dot access stays verbatim under the package's strict flags. HAND-MAINTAINED:
4
+ * there is no generator, so a new class in `app-brand.module.css` must be added here too.
5
+ */
6
+ declare const classes: {
7
+ readonly zone: string
8
+ readonly brand: string
9
+ readonly brandLead: string
10
+ readonly brandName: string
11
+ readonly brandButton: string
12
+ readonly ghostIcon: string
13
+ }
14
+ export default classes
@@ -0,0 +1,140 @@
1
+ /**
2
+ * `AppBrand` — the brand identity plus the sidebar-collapse toggle, rendered as the HEADER's
3
+ * leading zone.
4
+ *
5
+ * It used to be the sidebar's own first row, an `appShellHeaderHeight` band under `layout="alt"`
6
+ * where the header was inset beside the navbar and the two bands sat side by side. With the header
7
+ * spanning the full viewport width, that band became a SECOND 48px row painted under the header
8
+ * seam — two horizontal rules where the design has one. So the markup moved up into the header,
9
+ * unchanged: same `BrandConfig`, same `brand.menu` workspace switcher, same collapse toggle, same
10
+ * rail behaviour (the lead hides, the toggle centres).
11
+ *
12
+ * It is internal — `BasaltShell` is the only mount. `AppSidebar` still takes `brand` because
13
+ * `brand.version` labels its settings footer; it simply no longer paints the row.
14
+ */
15
+ import { ActionIcon, Group, Menu, Text, UnstyledButton } from '@mantine/core'
16
+ import { cx } from '../common/props'
17
+ import type { BasaltProps } from '../common/props'
18
+ import type { AccountMenuItem } from './account-types'
19
+ import type { BrandConfig } from './index'
20
+ import { IconChevron } from './sidebar-blocks'
21
+ import { VX } from '../tokens'
22
+ import { useBasaltSpacing } from '../theme'
23
+ import classes from './app-brand.module.css'
24
+
25
+ /** Inline collapse/expand chevrons — keeps the shell icon-dependency-free. */
26
+ function IconCollapse({ collapsed }: { collapsed: boolean }) {
27
+ return (
28
+ <svg
29
+ width={18}
30
+ height={18}
31
+ viewBox="0 0 24 24"
32
+ fill="none"
33
+ stroke="currentColor"
34
+ strokeWidth={2}
35
+ strokeLinecap="round"
36
+ strokeLinejoin="round"
37
+ aria-hidden
38
+ >
39
+ <path d="M4 4h16v16H4z" />
40
+ <path d="M9 4v16" />
41
+ {collapsed ? <path d="M14 9l3 3l-3 3" /> : <path d="M16 9l-3 3l3 3" />}
42
+ </svg>
43
+ )
44
+ }
45
+
46
+ /**
47
+ * The brand name, and — when `brand.menu` is supplied — the workspace switcher it becomes.
48
+ *
49
+ * The entries are `AccountMenuItem`s: the shell already had exactly this row shape (label, icon,
50
+ * onClick, danger) for the account menu, and a second vocabulary for the same dropdown would be
51
+ * two things to keep in step for no gain. The chevron is inline text, not an icon dependency.
52
+ */
53
+ function BrandName({
54
+ brand,
55
+ menuWidth,
56
+ }: {
57
+ brand: BrandConfig & { menu?: AccountMenuItem[] }
58
+ menuWidth: number
59
+ }) {
60
+ const label = (
61
+ <Text className={classes.brandName} fz={VX.text.xl} fw={550}>
62
+ {brand.name}
63
+ </Text>
64
+ )
65
+ const menu = brand.menu
66
+ if (menu === undefined || menu.length === 0) return label
67
+
68
+ return (
69
+ <Menu position="bottom-start" withArrow width={menuWidth} zIndex={500}>
70
+ <Menu.Target>
71
+ <UnstyledButton className={classes.brandButton} aria-label={`${brand.name} workspace`}>
72
+ {label}
73
+ {/* `open` is the DOWN glyph — a switcher's affordance points at its dropdown, and this is
74
+ the same chevron every fold in the sidebar uses rather than a second one. */}
75
+ <IconChevron open />
76
+ </UnstyledButton>
77
+ </Menu.Target>
78
+ <Menu.Dropdown>
79
+ {menu.map((entry) => (
80
+ <Menu.Item
81
+ key={entry.key}
82
+ leftSection={entry.icon}
83
+ {...(entry.danger === true && { color: 'red' })}
84
+ onClick={entry.onClick}
85
+ >
86
+ {entry.label}
87
+ </Menu.Item>
88
+ ))}
89
+ </Menu.Dropdown>
90
+ </Menu>
91
+ )
92
+ }
93
+
94
+ export type AppBrandProps = BasaltProps & {
95
+ brand: BrandConfig & { menu?: AccountMenuItem[] }
96
+ /** Desktop rail state — the zone narrows with the navbar and shows the toggle alone. */
97
+ collapsed: boolean
98
+ onToggleCollapse: () => void
99
+ }
100
+
101
+ export function AppBrand({ brand, collapsed, onToggleCollapse, className, style }: AppBrandProps) {
102
+ // Density-tracking Menu dropdown width, read at the ACTIVE resolved level — same reason
103
+ // `AppSidebar` reads it rather than the frozen level-0 constant (`tokens/palette.ts`).
104
+ const { step } = useBasaltSpacing()
105
+ return (
106
+ <Group
107
+ className={cx(classes.brand, className)}
108
+ gap="sm"
109
+ wrap="nowrap"
110
+ {...(style !== undefined && { style })}
111
+ >
112
+ <Group className={classes.brandLead} gap="sm" wrap="nowrap">
113
+ {brand.logoSrc && (
114
+ <img
115
+ src={brand.logoSrc}
116
+ alt={brand.logoAlt ?? brand.name}
117
+ width={26}
118
+ height={26}
119
+ style={{ display: 'block' }}
120
+ />
121
+ )}
122
+ <BrandName brand={brand} menuWidth={step.sidebarAccountMenuWidth} />
123
+ </Group>
124
+ <ActionIcon
125
+ variant="subtle"
126
+ // A numeric size, not the named `"md"` — same opt-out as `connectivity-indicator.tsx`'s
127
+ // toolbar icon (see that comment): this is a plain collapse-toggle icon, not a control meant
128
+ // to match a `size="md"` Input/Button, so it must not pick up the theme's `ActionIcon.extend`
129
+ // control-height override. Reproduces Mantine's own static `--ai-size-md` (28px).
130
+ size={28}
131
+ visibleFrom="sm"
132
+ className={classes.ghostIcon}
133
+ onClick={onToggleCollapse}
134
+ aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
135
+ >
136
+ <IconCollapse collapsed={collapsed} />
137
+ </ActionIcon>
138
+ </Group>
139
+ )
140
+ }
@@ -14,6 +14,7 @@ import { Anchor, Group, Text } from '@mantine/core'
14
14
  import type { CSSProperties } from 'react'
15
15
  import type { NavAnchor } from '../nav/types'
16
16
  import { VX } from '../tokens'
17
+ import type { BasaltProps } from '../common/props'
17
18
  import classes from './app-header.module.css'
18
19
 
19
20
  /** Parent/section crumbs — faint. */
@@ -31,13 +32,7 @@ const currentStyle: CSSProperties = {
31
32
  color: 'var(--vx-ink)',
32
33
  }
33
34
 
34
- export function AppBreadcrumbs({
35
- section,
36
- parent,
37
- parentAnchor,
38
- parentHref,
39
- page,
40
- }: {
35
+ export type AppBreadcrumbsProps = BasaltProps & {
41
36
  section?: string
42
37
  /** Parent item label — shown when the active page is a nested child (e.g. "Dashboard"). */
43
38
  parent?: string | undefined
@@ -49,10 +44,25 @@ export function AppBreadcrumbs({
49
44
  /** Parent item href — the no-router fallback; ignored when `parentAnchor` is present. */
50
45
  parentHref?: string | undefined
51
46
  page?: string
52
- }) {
47
+ }
48
+
49
+ export function AppBreadcrumbs({
50
+ section,
51
+ parent,
52
+ parentAnchor,
53
+ parentHref,
54
+ page,
55
+ className,
56
+ style,
57
+ }: AppBreadcrumbsProps) {
53
58
  if (!page) return null
54
59
  return (
55
- <Group gap={6} wrap="nowrap" style={{ minWidth: 0 }}>
60
+ <Group
61
+ gap={6}
62
+ wrap="nowrap"
63
+ {...(className !== undefined && { className })}
64
+ style={{ minWidth: 0, ...style }}
65
+ >
56
66
  {/*
57
67
  The ANCESTOR crumbs, in one box so CSS can drop them below `sm` — law C9's swap, owned by the
58
68
  component, no JS media query and no first-paint flash. On a phone the header row is the