basalt-ui 1.25.0 → 1.27.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 (476) hide show
  1. package/AGENTS.md +8 -6
  2. package/CHANGELOG.md +26 -0
  3. package/MIGRATING.md +815 -23
  4. package/README.md +45 -32
  5. package/agent/rules/basalt-batteries.md +205 -0
  6. package/agent/rules/basalt-charts.md +125 -555
  7. package/agent/rules/basalt-controls.md +160 -0
  8. package/agent/rules/basalt-mantine.md +146 -439
  9. package/agent/rules/basalt-state.md +118 -96
  10. package/agent/rules/basalt-tokens.md +126 -288
  11. package/agent/skills/basalt-app/SKILL.md +70 -195
  12. package/agent/skills/basalt-charts/SKILL.md +54 -234
  13. package/agent/skills/basalt-design/SKILL.md +56 -248
  14. package/agent/templates/CLAUDE-block.md.tpl +31 -40
  15. package/agent/templates/DESIGN.md.tpl +22 -51
  16. package/configs/oxlint-plugin.js +1465 -36
  17. package/configs/oxlint-plugin.test.ts +1190 -11
  18. package/configs/oxlint.json +11 -3
  19. package/dist/charts/cursor/resolve.d.ts +18 -0
  20. package/dist/charts/cursor/resolve.d.ts.map +1 -1
  21. package/dist/charts/cursor/resolve.js +15 -6
  22. package/dist/charts/cursor/scope.d.ts +6 -3
  23. package/dist/charts/cursor/scope.d.ts.map +1 -1
  24. package/dist/charts/cursor/store.d.ts +5 -1
  25. package/dist/charts/cursor/store.d.ts.map +1 -1
  26. package/dist/charts/cursor/store.js +4 -4
  27. package/dist/charts/hooks/useChartCursor.d.ts.map +1 -1
  28. package/dist/charts/hooks/useChartCursor.js +9 -8
  29. package/dist/charts/index.d.ts +2 -2
  30. package/dist/charts/index.d.ts.map +1 -1
  31. package/dist/charts/primitives/ChartCard.d.ts +34 -9
  32. package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
  33. package/dist/charts/primitives/ChartCard.js +29 -114
  34. package/dist/charts/primitives/ChartCard.test.d.ts +2 -0
  35. package/dist/charts/primitives/ChartCard.test.d.ts.map +1 -0
  36. package/dist/charts/sparklines/BarSparkline.d.ts +26 -2
  37. package/dist/charts/sparklines/BarSparkline.d.ts.map +1 -1
  38. package/dist/charts/sparklines/BarSparkline.js +18 -4
  39. package/dist/cli/check-coverage.test.d.ts +2 -0
  40. package/dist/cli/check-coverage.test.d.ts.map +1 -0
  41. package/dist/cli/index.d.ts +67 -4
  42. package/dist/cli/index.d.ts.map +1 -1
  43. package/dist/cli/index.js +225 -7
  44. package/dist/connectivity/connectivity-indicator.d.ts +4 -1
  45. package/dist/connectivity/connectivity-indicator.d.ts.map +1 -1
  46. package/dist/connectivity/connectivity-indicator.js +1 -1
  47. package/dist/content/index.d.ts +5 -3
  48. package/dist/content/index.d.ts.map +1 -1
  49. package/dist/content/index.js +4 -2
  50. package/dist/content/prose.module.css +7 -28
  51. package/dist/controls/actions.d.ts +169 -0
  52. package/dist/controls/actions.d.ts.map +1 -0
  53. package/dist/controls/actions.js +287 -0
  54. package/dist/controls/actions.module.css +62 -0
  55. package/dist/controls/actions.module.css.d.ts +13 -0
  56. package/dist/controls/actions.test.d.ts +2 -0
  57. package/dist/controls/actions.test.d.ts.map +1 -0
  58. package/dist/controls/actions.type-guard.test.d.ts +2 -0
  59. package/dist/controls/actions.type-guard.test.d.ts.map +1 -0
  60. package/dist/controls/compare-filter.d.ts +41 -0
  61. package/dist/controls/compare-filter.d.ts.map +1 -0
  62. package/dist/controls/compare-filter.js +23 -0
  63. package/dist/controls/control-group.d.ts +19 -0
  64. package/dist/controls/control-group.d.ts.map +1 -0
  65. package/dist/controls/control-group.js +20 -0
  66. package/dist/controls/control-group.test.d.ts +2 -0
  67. package/dist/controls/control-group.test.d.ts.map +1 -0
  68. package/dist/controls/controls.module.css +542 -0
  69. package/dist/controls/controls.module.css.d.ts +35 -0
  70. package/dist/controls/controls.router.test.d.ts +2 -0
  71. package/dist/controls/controls.router.test.d.ts.map +1 -0
  72. package/dist/controls/enum-filter.d.ts +39 -0
  73. package/dist/controls/enum-filter.d.ts.map +1 -0
  74. package/dist/controls/enum-filter.js +93 -0
  75. package/dist/controls/filter-context.d.ts +60 -0
  76. package/dist/controls/filter-context.d.ts.map +1 -0
  77. package/dist/controls/filter-context.js +69 -0
  78. package/dist/controls/filter-pill.d.ts +28 -0
  79. package/dist/controls/filter-pill.d.ts.map +1 -0
  80. package/dist/controls/filter-pill.js +70 -0
  81. package/dist/controls/filter-set.d.ts +13 -0
  82. package/dist/controls/filter-set.d.ts.map +1 -0
  83. package/dist/controls/filter-set.js +125 -0
  84. package/dist/controls/filter-set.test.d.ts +2 -0
  85. package/dist/controls/filter-set.test.d.ts.map +1 -0
  86. package/dist/controls/filter-sheet.d.ts +117 -0
  87. package/dist/controls/filter-sheet.d.ts.map +1 -0
  88. package/dist/controls/filter-sheet.js +146 -0
  89. package/dist/controls/glyphs.d.ts +27 -0
  90. package/dist/controls/glyphs.d.ts.map +1 -0
  91. package/dist/controls/glyphs.js +49 -0
  92. package/dist/controls/index.d.ts +20 -0
  93. package/dist/controls/index.d.ts.map +1 -0
  94. package/dist/controls/index.js +46 -0
  95. package/dist/controls/multi-select-filter.d.ts +23 -0
  96. package/dist/controls/multi-select-filter.d.ts.map +1 -0
  97. package/dist/controls/multi-select-filter.js +89 -0
  98. package/dist/controls/number-filter.d.ts +26 -0
  99. package/dist/controls/number-filter.d.ts.map +1 -0
  100. package/dist/controls/number-filter.js +143 -0
  101. package/dist/controls/peer-boundary.test.d.ts +2 -0
  102. package/dist/controls/peer-boundary.test.d.ts.map +1 -0
  103. package/dist/controls/props-contract.test.d.ts +2 -0
  104. package/dist/controls/props-contract.test.d.ts.map +1 -0
  105. package/dist/controls/range-filter.d.ts +43 -0
  106. package/dist/controls/range-filter.d.ts.map +1 -0
  107. package/dist/controls/range-filter.js +135 -0
  108. package/dist/controls/range-filter.type-guard.test.d.ts +2 -0
  109. package/dist/controls/range-filter.type-guard.test.d.ts.map +1 -0
  110. package/dist/controls/search-filter.d.ts +10 -0
  111. package/dist/controls/search-filter.d.ts.map +1 -0
  112. package/dist/controls/search-filter.js +81 -0
  113. package/dist/controls/select-filter.d.ts +74 -0
  114. package/dist/controls/select-filter.d.ts.map +1 -0
  115. package/dist/controls/select-filter.js +10 -0
  116. package/dist/controls/sync-button.d.ts +38 -0
  117. package/dist/controls/sync-button.d.ts.map +1 -0
  118. package/dist/controls/sync-button.js +119 -0
  119. package/dist/controls/sync-button.module.css +63 -0
  120. package/dist/controls/sync-button.module.css.d.ts +11 -0
  121. package/dist/controls/sync-button.test.d.ts +2 -0
  122. package/dist/controls/sync-button.test.d.ts.map +1 -0
  123. package/dist/controls/toggle-filter.d.ts +9 -0
  124. package/dist/controls/toggle-filter.d.ts.map +1 -0
  125. package/dist/controls/toggle-filter.js +42 -0
  126. package/dist/controls/view-tabs.d.ts +23 -0
  127. package/dist/controls/view-tabs.d.ts.map +1 -0
  128. package/dist/controls/view-tabs.js +59 -0
  129. package/dist/controls-dates/date-range-picker.d.ts +4 -0
  130. package/dist/controls-dates/date-range-picker.d.ts.map +1 -0
  131. package/dist/controls-dates/date-range-picker.js +18 -0
  132. package/dist/controls-dates/index.d.ts +9 -0
  133. package/dist/controls-dates/index.d.ts.map +1 -0
  134. package/dist/controls-dates/index.js +4 -0
  135. package/dist/dashboard/delta-badge.d.ts +6 -12
  136. package/dist/dashboard/delta-badge.d.ts.map +1 -1
  137. package/dist/dashboard/delta-badge.js +1 -50
  138. package/dist/dashboard/index.d.ts +1 -1
  139. package/dist/dashboard/index.d.ts.map +1 -1
  140. package/dist/dashboard/index.js +3 -1
  141. package/dist/dashboard/settings-section.d.ts +6 -4
  142. package/dist/dashboard/settings-section.d.ts.map +1 -1
  143. package/dist/dashboard/settings-section.js +23 -16
  144. package/dist/dashboard/settings-section.module.css +10 -0
  145. package/dist/dashboard/settings-section.module.css.d.ts +1 -0
  146. package/dist/dashboard/settings-section.test.d.ts +2 -0
  147. package/dist/dashboard/settings-section.test.d.ts.map +1 -0
  148. package/dist/dashboard/stat-card.d.ts +95 -9
  149. package/dist/dashboard/stat-card.d.ts.map +1 -1
  150. package/dist/dashboard/stat-card.js +108 -49
  151. package/dist/dashboard/stat-card.module.css +153 -0
  152. package/dist/dashboard/stat-card.module.css.d.ts +15 -0
  153. package/dist/data/data-table.d.ts +37 -15
  154. package/dist/data/data-table.d.ts.map +1 -1
  155. package/dist/data/data-table.js +96 -58
  156. package/dist/guard/grace.test.d.ts +20 -0
  157. package/dist/guard/grace.test.d.ts.map +1 -0
  158. package/dist/guard/index.d.ts +66 -3
  159. package/dist/guard/index.d.ts.map +1 -1
  160. package/dist/guard/index.js +78 -7
  161. package/dist/guard/types.d.ts +3 -3
  162. package/dist/guard/types.d.ts.map +1 -1
  163. package/dist/index.d.ts +13 -3
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js +13 -10
  166. package/dist/nav/types.d.ts +78 -2
  167. package/dist/nav/types.d.ts.map +1 -1
  168. package/dist/notifications/bell.d.ts +4 -1
  169. package/dist/notifications/bell.d.ts.map +1 -1
  170. package/dist/notifications/index.d.ts +1 -1
  171. package/dist/router-tanstack/field.d.ts +14 -0
  172. package/dist/router-tanstack/field.d.ts.map +1 -0
  173. package/dist/router-tanstack/field.js +4 -0
  174. package/dist/router-tanstack/index.d.ts +6 -2
  175. package/dist/router-tanstack/index.d.ts.map +1 -1
  176. package/dist/router-tanstack/index.js +4 -0
  177. package/dist/router-tanstack/multi-search-param-store.d.ts +4 -52
  178. package/dist/router-tanstack/multi-search-param-store.d.ts.map +1 -1
  179. package/dist/router-tanstack/multi-search-param-store.js +19 -27
  180. package/dist/router-tanstack/search-param-store.d.ts +3 -87
  181. package/dist/router-tanstack/search-param-store.d.ts.map +1 -1
  182. package/dist/router-tanstack/search-param-store.js +16 -45
  183. package/dist/router-tanstack/search-store.d.ts +84 -0
  184. package/dist/router-tanstack/search-store.d.ts.map +1 -0
  185. package/dist/router-tanstack/search-store.js +271 -0
  186. package/dist/router-tanstack/search-store.router.test.d.ts +2 -0
  187. package/dist/router-tanstack/search-store.router.test.d.ts.map +1 -0
  188. package/dist/router-tanstack/search-store.test.d.ts +2 -0
  189. package/dist/router-tanstack/search-store.test.d.ts.map +1 -0
  190. package/dist/router-tanstack/use-nav.d.ts +0 -2
  191. package/dist/router-tanstack/use-nav.d.ts.map +1 -1
  192. package/dist/router-tanstack/use-nav.js +34 -12
  193. package/dist/router-tanstack/use-nav.test.d.ts +2 -0
  194. package/dist/router-tanstack/use-nav.test.d.ts.map +1 -0
  195. package/dist/section/index.d.ts +2 -0
  196. package/dist/section/index.d.ts.map +1 -0
  197. package/dist/section/index.js +4 -0
  198. package/dist/section/section.d.ts +24 -0
  199. package/dist/section/section.d.ts.map +1 -0
  200. package/dist/section/section.js +126 -0
  201. package/dist/section/section.module.css +104 -0
  202. package/dist/section/section.module.css.d.ts +11 -0
  203. package/dist/section/section.test.d.ts +2 -0
  204. package/dist/section/section.test.d.ts.map +1 -0
  205. package/dist/shell/app-breadcrumbs.d.ts.map +1 -1
  206. package/dist/shell/app-breadcrumbs.js +18 -15
  207. package/dist/shell/app-header.module.css +77 -37
  208. package/dist/shell/app-header.module.css.d.ts +2 -1
  209. package/dist/shell/app-mobile-nav.d.ts +9 -2
  210. package/dist/shell/app-mobile-nav.d.ts.map +1 -1
  211. package/dist/shell/app-mobile-nav.js +98 -11
  212. package/dist/shell/app-mobile-nav.module.css +8 -0
  213. package/dist/shell/app-mobile-nav.module.css.d.ts +1 -0
  214. package/dist/shell/app-sidebar.d.ts +55 -28
  215. package/dist/shell/app-sidebar.d.ts.map +1 -1
  216. package/dist/shell/app-sidebar.js +116 -67
  217. package/dist/shell/app-sidebar.module.css +303 -20
  218. package/dist/shell/app-sidebar.module.css.d.ts +19 -1
  219. package/dist/shell/index.d.ts +55 -21
  220. package/dist/shell/index.d.ts.map +1 -1
  221. package/dist/shell/index.js +40 -18
  222. package/dist/shell/mobile-nav-model.d.ts +13 -2
  223. package/dist/shell/mobile-nav-model.d.ts.map +1 -1
  224. package/dist/shell/mobile-nav-model.js +15 -1
  225. package/dist/shell/nav-count-badge.d.ts +1 -1
  226. package/dist/shell/page-bar.d.ts +51 -0
  227. package/dist/shell/page-bar.d.ts.map +1 -0
  228. package/dist/shell/page-bar.js +154 -0
  229. package/dist/shell/page-bar.module.css +178 -0
  230. package/dist/shell/page-bar.module.css.d.ts +17 -0
  231. package/dist/shell/page-bar.test.d.ts +2 -0
  232. package/dist/shell/page-bar.test.d.ts.map +1 -0
  233. package/dist/shell/sidebar-block-model.d.ts +48 -0
  234. package/dist/shell/sidebar-block-model.d.ts.map +1 -0
  235. package/dist/shell/sidebar-block-model.js +39 -0
  236. package/dist/shell/sidebar-blocks.d.ts +32 -0
  237. package/dist/shell/sidebar-blocks.d.ts.map +1 -0
  238. package/dist/shell/sidebar-blocks.js +169 -0
  239. package/dist/shell/sidebar-search.d.ts +13 -1
  240. package/dist/shell/sidebar-search.d.ts.map +1 -1
  241. package/dist/shell/sidebar-search.js +34 -1
  242. package/dist/shell/sidebar-search.module.css +26 -0
  243. package/dist/shell/sidebar-search.module.css.d.ts +2 -0
  244. package/dist/state/fields.d.ts +565 -0
  245. package/dist/state/fields.d.ts.map +1 -0
  246. package/dist/state/fields.js +405 -0
  247. package/dist/state/fields.test.d.ts +2 -0
  248. package/dist/state/fields.test.d.ts.map +1 -0
  249. package/dist/state/persisted.d.ts +60 -0
  250. package/dist/state/persisted.d.ts.map +1 -0
  251. package/dist/state/persisted.js +123 -0
  252. package/dist/state/persisted.test.d.ts +2 -0
  253. package/dist/state/persisted.test.d.ts.map +1 -0
  254. package/dist/state.d.ts +11 -56
  255. package/dist/state.d.ts.map +1 -1
  256. package/dist/state.js +14 -120
  257. package/dist/styles.css +13 -0
  258. package/dist/surfaces.d.ts +106 -24
  259. package/dist/surfaces.d.ts.map +1 -1
  260. package/dist/surfaces.js +156 -19
  261. package/dist/theme/controls.module.css +16 -1
  262. package/dist/theme/ctl-theme.d.ts +32 -0
  263. package/dist/theme/ctl-theme.d.ts.map +1 -0
  264. package/dist/theme/ctl-theme.js +54 -0
  265. package/dist/theme/ctl-theme.test.d.ts +2 -0
  266. package/dist/theme/ctl-theme.test.d.ts.map +1 -0
  267. package/dist/theme/ctl-tier-coverage.test.d.ts +2 -0
  268. package/dist/theme/ctl-tier-coverage.test.d.ts.map +1 -0
  269. package/dist/theme/divider-law.test.d.ts +2 -0
  270. package/dist/theme/divider-law.test.d.ts.map +1 -0
  271. package/dist/theme/icon-slot.d.ts +44 -0
  272. package/dist/theme/icon-slot.d.ts.map +1 -0
  273. package/dist/theme/icon-slot.js +21 -0
  274. package/dist/theme/icon-slot.module.css +47 -0
  275. package/dist/theme/icon-slot.module.css.d.ts +8 -0
  276. package/dist/theme/icon-slot.test.d.ts +2 -0
  277. package/dist/theme/icon-slot.test.d.ts.map +1 -0
  278. package/dist/theme/index.d.ts +1 -0
  279. package/dist/theme/index.d.ts.map +1 -1
  280. package/dist/theme/index.js +82 -5
  281. package/dist/theme/layout-rhythm-css.test.d.ts +2 -0
  282. package/dist/theme/layout-rhythm-css.test.d.ts.map +1 -0
  283. package/dist/theme/segmented-control.module.css +20 -0
  284. package/dist/theme/shadow-surfaces.test.d.ts.map +1 -1
  285. package/dist/tokens/index.d.ts +12 -0
  286. package/dist/tokens/index.d.ts.map +1 -1
  287. package/dist/tokens/index.js +38 -8
  288. package/dist/tokens/palette.d.ts +97 -61
  289. package/dist/tokens/palette.d.ts.map +1 -1
  290. package/dist/tokens/palette.js +76 -38
  291. package/dist/tokens.css +10 -2
  292. package/dist/widget-header/delta-badge.d.ts +13 -0
  293. package/dist/widget-header/delta-badge.d.ts.map +1 -0
  294. package/dist/widget-header/delta-badge.js +29 -0
  295. package/dist/widget-header/delta-badge.test.d.ts +2 -0
  296. package/dist/widget-header/delta-badge.test.d.ts.map +1 -0
  297. package/dist/widget-header/index.d.ts +3 -0
  298. package/dist/widget-header/index.d.ts.map +1 -0
  299. package/dist/widget-header/index.js +6 -0
  300. package/dist/widget-header/no-mantine.test.d.ts +2 -0
  301. package/dist/widget-header/no-mantine.test.d.ts.map +1 -0
  302. package/dist/widget-header/widget-header.d.ts +67 -0
  303. package/dist/widget-header/widget-header.d.ts.map +1 -0
  304. package/dist/widget-header/widget-header.js +89 -0
  305. package/dist/widget-header/widget-header.module.css +350 -0
  306. package/dist/widget-header/widget-header.module.css.d.ts +25 -0
  307. package/dist/widget-header/widget-header.test.d.ts +2 -0
  308. package/dist/widget-header/widget-header.test.d.ts.map +1 -0
  309. package/llms.txt +30 -17
  310. package/package.json +14 -1
  311. package/src/charts/cursor/resolve.test.ts +29 -1
  312. package/src/charts/cursor/resolve.ts +38 -6
  313. package/src/charts/cursor/scope.tsx +6 -3
  314. package/src/charts/cursor/store.test.ts +19 -1
  315. package/src/charts/cursor/store.ts +10 -5
  316. package/src/charts/hooks/useChartCursor.ts +16 -8
  317. package/src/charts/index.ts +2 -2
  318. package/src/charts/primitives/CartesianChart.test.tsx +124 -0
  319. package/src/charts/primitives/ChartCard.test.tsx +66 -0
  320. package/src/charts/primitives/ChartCard.tsx +86 -146
  321. package/src/charts/sparklines/BarSparkline.tsx +43 -5
  322. package/src/cli/check-coverage.test.ts +297 -0
  323. package/src/cli/check-theme.test.ts +38 -14
  324. package/src/cli/index.ts +392 -16
  325. package/src/cli/init-sync.test.ts +97 -0
  326. package/src/connectivity/connectivity-indicator.tsx +16 -9
  327. package/src/content/index.ts +16 -3
  328. package/src/content/prose.module.css +7 -28
  329. package/src/content/prose.module.css.test.ts +8 -24
  330. package/src/controls/actions.module.css +62 -0
  331. package/src/controls/actions.module.css.d.ts +13 -0
  332. package/src/controls/actions.test.tsx +252 -0
  333. package/src/controls/actions.tsx +655 -0
  334. package/src/controls/actions.type-guard.test.ts +63 -0
  335. package/src/controls/compare-filter.tsx +64 -0
  336. package/src/controls/control-group.test.tsx +229 -0
  337. package/src/controls/control-group.tsx +63 -0
  338. package/src/controls/controls.module.css +542 -0
  339. package/src/controls/controls.module.css.d.ts +35 -0
  340. package/src/controls/controls.router.test.tsx +1053 -0
  341. package/src/controls/enum-filter.tsx +170 -0
  342. package/src/controls/filter-context.tsx +158 -0
  343. package/src/controls/filter-pill.tsx +120 -0
  344. package/src/controls/filter-set.test.tsx +472 -0
  345. package/src/controls/filter-set.tsx +225 -0
  346. package/src/controls/filter-sheet.tsx +285 -0
  347. package/src/controls/glyphs.tsx +81 -0
  348. package/src/controls/index.ts +49 -0
  349. package/src/controls/multi-select-filter.tsx +140 -0
  350. package/src/controls/number-filter.tsx +291 -0
  351. package/src/controls/peer-boundary.test.ts +85 -0
  352. package/src/controls/props-contract.test.tsx +137 -0
  353. package/src/controls/range-filter.tsx +237 -0
  354. package/src/controls/range-filter.type-guard.test.tsx +122 -0
  355. package/src/controls/search-filter.tsx +123 -0
  356. package/src/controls/select-filter.tsx +89 -0
  357. package/src/controls/sync-button.module.css +63 -0
  358. package/src/controls/sync-button.module.css.d.ts +11 -0
  359. package/src/controls/sync-button.test.tsx +183 -0
  360. package/src/controls/sync-button.tsx +197 -0
  361. package/src/controls/toggle-filter.tsx +60 -0
  362. package/src/controls/view-tabs.tsx +110 -0
  363. package/src/controls-dates/date-range-picker.tsx +42 -0
  364. package/src/controls-dates/index.ts +8 -0
  365. package/src/dashboard/delta-badge.tsx +4 -74
  366. package/src/dashboard/index.ts +6 -1
  367. package/src/dashboard/settings-section.module.css +10 -0
  368. package/src/dashboard/settings-section.module.css.d.ts +1 -0
  369. package/src/dashboard/settings-section.test.tsx +56 -0
  370. package/src/dashboard/settings-section.tsx +33 -30
  371. package/src/dashboard/stat-card.module.css +153 -0
  372. package/src/dashboard/stat-card.module.css.d.ts +15 -0
  373. package/src/dashboard/stat-card.test.tsx +298 -1
  374. package/src/dashboard/stat-card.tsx +289 -67
  375. package/src/data/data-table.test.tsx +96 -11
  376. package/src/data/data-table.tsx +228 -84
  377. package/src/guard/check-source.test.ts +159 -13
  378. package/src/guard/grace.test.ts +158 -0
  379. package/src/guard/index.ts +185 -29
  380. package/src/guard/types.ts +4 -2
  381. package/src/index.ts +51 -5
  382. package/src/nav/types.ts +84 -2
  383. package/src/notifications/bell.tsx +6 -3
  384. package/src/notifications/index.ts +1 -1
  385. package/src/router-tanstack/field.ts +35 -0
  386. package/src/router-tanstack/index.ts +28 -2
  387. package/src/router-tanstack/multi-search-param-store.test.ts +71 -3
  388. package/src/router-tanstack/multi-search-param-store.ts +46 -77
  389. package/src/router-tanstack/search-param-store.ts +42 -159
  390. package/src/router-tanstack/search-store.router.test.tsx +882 -0
  391. package/src/router-tanstack/search-store.test.ts +578 -0
  392. package/src/router-tanstack/search-store.ts +546 -0
  393. package/src/router-tanstack/use-nav.test.tsx +187 -0
  394. package/src/router-tanstack/use-nav.ts +72 -14
  395. package/src/section/index.ts +1 -0
  396. package/src/section/section.module.css +104 -0
  397. package/src/section/section.module.css.d.ts +11 -0
  398. package/src/section/section.test.tsx +204 -0
  399. package/src/section/section.tsx +220 -0
  400. package/src/shell/app-breadcrumbs.tsx +44 -31
  401. package/src/shell/app-header.module.css +77 -37
  402. package/src/shell/app-header.module.css.d.ts +2 -1
  403. package/src/shell/app-mobile-nav.module.css +8 -0
  404. package/src/shell/app-mobile-nav.module.css.d.ts +1 -0
  405. package/src/shell/app-mobile-nav.tsx +147 -8
  406. package/src/shell/app-sidebar-account.tsx +2 -2
  407. package/src/shell/app-sidebar.module.css +303 -20
  408. package/src/shell/app-sidebar.module.css.d.ts +19 -1
  409. package/src/shell/app-sidebar.test.tsx +456 -41
  410. package/src/shell/app-sidebar.tsx +276 -140
  411. package/src/shell/index.test.tsx +291 -5
  412. package/src/shell/index.tsx +137 -38
  413. package/src/shell/mobile-nav-model.test.ts +228 -7
  414. package/src/shell/mobile-nav-model.ts +53 -3
  415. package/src/shell/nav-count-badge.tsx +1 -1
  416. package/src/shell/page-bar.module.css +178 -0
  417. package/src/shell/page-bar.module.css.d.ts +17 -0
  418. package/src/shell/page-bar.test.tsx +316 -0
  419. package/src/shell/page-bar.tsx +315 -0
  420. package/src/shell/sidebar-block-model.ts +83 -0
  421. package/src/shell/sidebar-blocks.tsx +301 -0
  422. package/src/shell/sidebar-search.module.css +26 -0
  423. package/src/shell/sidebar-search.module.css.d.ts +2 -0
  424. package/src/shell/sidebar-search.tsx +71 -2
  425. package/src/state/fields.test.tsx +512 -0
  426. package/src/state/fields.ts +1150 -0
  427. package/src/state/persisted.test.ts +91 -0
  428. package/src/state/persisted.ts +261 -0
  429. package/src/state.ts +52 -240
  430. package/src/styles.css +13 -0
  431. package/src/surfaces.ts +204 -36
  432. package/src/theme/controls.module.css +16 -1
  433. package/src/theme/ctl-theme.test.tsx +275 -0
  434. package/src/theme/ctl-theme.tsx +138 -0
  435. package/src/theme/ctl-tier-coverage.test.ts +170 -0
  436. package/src/theme/density-relations.test.ts +106 -51
  437. package/src/theme/divider-law.test.ts +259 -0
  438. package/src/theme/icon-slot.module.css +47 -0
  439. package/src/theme/icon-slot.module.css.d.ts +8 -0
  440. package/src/theme/icon-slot.test.tsx +275 -0
  441. package/src/theme/icon-slot.tsx +59 -0
  442. package/src/theme/index.ts +165 -3
  443. package/src/theme/layout-rhythm-css.test.ts +72 -0
  444. package/src/theme/radius.test.ts +11 -1
  445. package/src/theme/segmented-control.module.css +20 -0
  446. package/src/theme/shadow-surfaces.test.ts +20 -7
  447. package/src/theme/spacing.test.ts +75 -27
  448. package/src/theme/use-basalt-spacing.ts +2 -2
  449. package/src/tokens/density.test.ts +7 -25
  450. package/src/tokens/index.ts +48 -8
  451. package/src/tokens/palette.ts +107 -73
  452. package/src/widget-header/delta-badge.test.tsx +60 -0
  453. package/src/widget-header/delta-badge.tsx +57 -0
  454. package/src/widget-header/index.ts +2 -0
  455. package/src/widget-header/no-mantine.test.ts +33 -0
  456. package/src/widget-header/widget-header.module.css +350 -0
  457. package/src/widget-header/widget-header.module.css.d.ts +25 -0
  458. package/src/widget-header/widget-header.test.tsx +187 -0
  459. package/src/widget-header/widget-header.tsx +213 -0
  460. package/agent/rules/basalt-agent.md +0 -452
  461. package/agent/rules/basalt-app.md +0 -246
  462. package/agent/rules/basalt-commands.md +0 -320
  463. package/agent/rules/basalt-content.md +0 -409
  464. package/agent/rules/basalt-data.md +0 -329
  465. package/agent/rules/basalt-forms.md +0 -186
  466. package/agent/rules/basalt-notifications.md +0 -264
  467. package/agent/rules/basalt-query.md +0 -187
  468. package/agent/rules/basalt-router.md +0 -336
  469. package/dist/content/article-filter-bar.d.ts +0 -40
  470. package/dist/content/article-filter-bar.d.ts.map +0 -1
  471. package/dist/content/article-filter-bar.js +0 -56
  472. package/dist/shell/page-header.d.ts +0 -13
  473. package/dist/shell/page-header.d.ts.map +0 -1
  474. package/dist/shell/page-header.js +0 -23
  475. package/src/content/article-filter-bar.tsx +0 -88
  476. package/src/shell/page-header.tsx +0 -35
@@ -1,7 +1,36 @@
1
1
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { Box, Card, Group, VisuallyHidden } from "@mantine/core";
3
- import { DeltaBadge } from "./delta-badge.js";
2
+ import { Box, Card, VisuallyHidden } from "@mantine/core";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { WidgetHeader } from "../widget-header/index.js";
5
+ import { CtlSlot } from "../theme/index.js";
4
6
  import { VX } from "../tokens/index.js";
7
+ import classes from "./stat-card.module.css";
8
+ const SPARKLINE_RIGHT_WIDTH = 72;
9
+ const SPARKLINE_RIGHT_HEIGHT = 26;
10
+ function useSlotWidth(active) {
11
+ const [width, setWidth] = useState(0);
12
+ const nodeRef = useRef(null);
13
+ useEffect(() => {
14
+ const node = nodeRef.current;
15
+ if (!active || node === null) return;
16
+ const measure = () => {
17
+ setWidth(node.getBoundingClientRect().width);
18
+ };
19
+ measure();
20
+ if (typeof ResizeObserver === "undefined") return;
21
+ const observer = new ResizeObserver(measure);
22
+ observer.observe(node);
23
+ return () => {
24
+ observer.disconnect();
25
+ };
26
+ }, [active]);
27
+ return {
28
+ ref: (node) => {
29
+ nodeRef.current = node;
30
+ },
31
+ width
32
+ };
33
+ }
5
34
  const TONE_RAIL_WIDTH = 3;
6
35
  const TONE_LABEL = {
7
36
  good: "Within the good threshold",
@@ -9,14 +38,26 @@ const TONE_LABEL = {
9
38
  bad: "Past the severe threshold"
10
39
  };
11
40
  function StatCard({
12
- label,
41
+ title,
42
+ icon,
43
+ subtitle,
44
+ info,
13
45
  value,
46
+ unit,
47
+ breakdown,
14
48
  delta,
15
49
  deltaPeriod,
50
+ deltaFormat,
51
+ deltaGlyph,
16
52
  sparkline,
17
- menu,
53
+ sparklinePlacement = "bleed",
54
+ actions,
18
55
  tone
19
56
  }) {
57
+ const isRender = typeof sparkline === "function";
58
+ const bleeds = sparklinePlacement === "bleed";
59
+ const slot = useSlotWidth(isRender);
60
+ const measured = { width: slot.width, height: SPARKLINE_RIGHT_HEIGHT };
20
61
  return /* @__PURE__ */ jsxs(
21
62
  Card,
22
63
  {
@@ -27,12 +68,13 @@ function StatCard({
27
68
  // shadow-card ring is unaffected (verified — only an ANCESTOR's overflow clips a
28
69
  // descendant's shadow). Mantine's Card root already sets `overflow: hidden`; this is
29
70
  // explicit for intent.
71
+ //
72
+ // NO `minHeight`. It was 118px, which is ~25px of dead space under a card holding a title
73
+ // row, a hero row and a 26px trend — and it was dead space the card could not use, since the
74
+ // body is `height: 100%` and the sparkline is `margin-top: auto`. The content is what states
75
+ // the height now (~88-96px), and four cards in a `SimpleGrid` still match because a grid row
76
+ // stretches its items.
30
77
  padding: "var(--mantine-spacing-xs) var(--mantine-spacing-sm)",
31
- minHeight: 118,
32
- display: "flex",
33
- // theme-allow inline-display — Card root as a flex column; Mantine Card takes no layout props
34
- flexDirection: "column",
35
- gap: "var(--vx-space-stat-card-gap)",
36
78
  overflow: "hidden",
37
79
  // Anchors the tone rail. Set unconditionally so a card's stacking context does not change
38
80
  // depending on whether it happens to have crossed a threshold this render.
@@ -60,50 +102,67 @@ function StatCard({
60
102
  }
61
103
  )
62
104
  ] }),
63
- /* @__PURE__ */ jsxs(Group, { justify: "space-between", align: "flex-start", wrap: "nowrap", gap: "xs", children: [
64
- /* @__PURE__ */ jsx(
65
- "span",
66
- {
67
- style: {
68
- fontFamily: "var(--basalt-font-mono)",
69
- fontSize: VX.text.xs,
70
- fontWeight: 500,
71
- letterSpacing: "0.06em",
72
- textTransform: "uppercase",
73
- color: VX.faint
105
+ /* @__PURE__ */ jsxs("div", { className: classes.body, "data-placement": sparklinePlacement, children: [
106
+ /* @__PURE__ */ jsxs("div", { className: classes.header, children: [
107
+ /* @__PURE__ */ jsx(
108
+ WidgetHeader,
109
+ {
110
+ tier: "widget",
111
+ title,
112
+ ...icon !== void 0 && { icon },
113
+ ...subtitle !== void 0 && { subtitle },
114
+ ...info !== void 0 && { info },
115
+ value,
116
+ ...unit !== void 0 && { unit },
117
+ ...delta !== void 0 && { delta },
118
+ ...deltaPeriod !== void 0 && { deltaPeriod },
119
+ ...deltaFormat !== void 0 && { deltaFormat },
120
+ ...deltaGlyph !== void 0 && { deltaGlyph },
121
+ ...actions !== void 0 && {
122
+ actions: /* @__PURE__ */ jsx(CtlSlot, { tier: "widget", children: actions })
123
+ }
124
+ }
125
+ ),
126
+ breakdown !== void 0 && breakdown.length > 0 && // A `<dl>`, not a table and not a stack of divs: each row IS a term and its value, which
127
+ // is the one semantic that survives a reader meeting the card out of context.
128
+ //
129
+ // INSIDE `.header`, not beside it: with `sparklinePlacement="right"` the body is a flex
130
+ // ROW, so a third child here would sit next to the trend rather than under the number
131
+ // it splits. The header block is the card's text column in both placements.
132
+ /* @__PURE__ */ jsx("dl", { className: classes.breakdown, children: breakdown.map((row) => /* @__PURE__ */ jsxs(
133
+ "div",
134
+ {
135
+ className: classes.breakdownRow,
136
+ ...row.tone !== void 0 && { "data-tone": row.tone },
137
+ children: [
138
+ /* @__PURE__ */ jsx("dt", { className: classes.breakdownLabel, children: row.label }),
139
+ /* @__PURE__ */ jsx("dd", { className: classes.breakdownValue, children: row.value })
140
+ ]
74
141
  },
75
- children: label
76
- }
77
- ),
78
- menu
79
- ] }),
80
- /* @__PURE__ */ jsxs(Group, { align: "center", gap: 8, wrap: "nowrap", children: [
81
- /* @__PURE__ */ jsx(
82
- "span",
142
+ row.label
143
+ )) })
144
+ ] }),
145
+ sparkline !== void 0 && /* @__PURE__ */ jsx(
146
+ "div",
83
147
  {
84
- style: {
85
- fontFamily: "var(--basalt-font-mono)",
86
- fontSize: VX.text.kpi,
87
- fontWeight: 600,
88
- letterSpacing: "-0.02em",
89
- color: VX.ink
148
+ ref: slot.ref,
149
+ className: bleeds ? classes.sparklineBleed : classes.sparklineRight,
150
+ ...!bleeds && {
151
+ // CUSTOM PROPERTIES, not `flexBasis`/`height` directly. A React inline style beats
152
+ // every stylesheet rule, so an inline `flexBasis: 72` also applied below `sm` — where
153
+ // `'right'` collapses to a COLUMN and flex-basis is therefore the main-axis HEIGHT.
154
+ // The mobile sparkline rendered in a 72px-tall box holding 26px of bars, which is the
155
+ // dead band under every KPI value on a phone. Handed to CSS as values instead, the
156
+ // media query can reset the box and the numbers still live in one place.
157
+ style: {
158
+ "--basalt-stat-sparkline-w": `${SPARKLINE_RIGHT_WIDTH}px`,
159
+ "--basalt-stat-sparkline-h": `${SPARKLINE_RIGHT_HEIGHT}px`
160
+ }
90
161
  },
91
- children: value
162
+ children: isRender ? measured.width > 0 && sparkline(measured) : sparkline
92
163
  }
93
- ),
94
- delta !== void 0 && /* @__PURE__ */ jsx(DeltaBadge, { value: delta, period: deltaPeriod })
95
- ] }),
96
- sparkline && /* @__PURE__ */ jsx(
97
- "div",
98
- {
99
- style: {
100
- marginTop: "auto",
101
- marginInline: "calc(-1 * var(--mantine-spacing-sm))",
102
- marginBottom: "calc(-1 * var(--mantine-spacing-xs))"
103
- },
104
- children: sparkline
105
- }
106
- )
164
+ )
165
+ ] })
107
166
  ]
108
167
  }
109
168
  );
@@ -0,0 +1,153 @@
1
+ /*
2
+ * StatCard's sparkline placement (docs/CONTROLS-SPEC.md §2.2). `bleed` (default) keeps the historic
3
+ * full-width row beneath the hero value, bled past the card's own inset padding — same negative
4
+ * margins the pre-WidgetHeader version drew inline. `right` sits the sparkline beside the
5
+ * `WidgetHeader`'s hero-value row instead, the reference-design look, and collapses back to
6
+ * `bleed`'s stacked layout below `sm` — CSS only, no JS branch (`47.99375em` is Mantine's own
7
+ * complement of `min-width: 48em`, same value `content/prose.module.css` derives it from).
8
+ */
9
+
10
+ .body {
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: var(--vx-space-stat-card-gap);
14
+ height: 100%;
15
+ }
16
+
17
+ /*
18
+ * `flex-end`, not `center`: the sparkline belongs to the HERO ROW, and the hero row is the header
19
+ * block's last line. Centred against the whole body it floated between the title and the value,
20
+ * which reads as a third, unrelated element; bottom-aligned to the header block it sits beside the
21
+ * number it describes, the reference layout. `gap` is the card's own control gap so the trend never
22
+ * touches a long value.
23
+ */
24
+ .body[data-placement='right'] {
25
+ flex-direction: row;
26
+ align-items: flex-end;
27
+ gap: var(--vx-space-control-gap);
28
+ }
29
+
30
+ .header {
31
+ min-width: 0;
32
+ }
33
+
34
+ /*
35
+ * `flex-shrink: 0` on the header, `1` on the sparkline slot below: the hero value and its delta keep
36
+ * their width and the TREND gives ground. The other way round, a 4-up KPI grid on a 1440 viewport
37
+ * ellipsized `$1,294,900` to `$1294.…` in order to keep 72px of bars intact, which is the wrong
38
+ * thing to protect. The value still carries `overflow: hidden` as the last resort, and `Card` clips.
39
+ */
40
+ .body[data-placement='right'] .header {
41
+ flex: 1 0 auto;
42
+ min-width: 0;
43
+ }
44
+
45
+ /*
46
+ * The `breakdown` rows — the two or three parts a hero number is made of, under it.
47
+ *
48
+ * NO hairline, anywhere in this block, and that is a law rather than a taste: `docs/CONTROLS-SPEC.md`
49
+ * §2.1 puts a horizontal rule between OPTION rows and nowhere else, and `theme/divider-law.test.ts`
50
+ * inventories every one basalt draws. Three rules inside a KPI card would read as a table wearing a
51
+ * card's clothes. The rows are separated by the stack rhythm and by weight — a muted label against
52
+ * an ink value — which is the same separation the sheet's own field groups use.
53
+ */
54
+ .breakdown {
55
+ display: flex;
56
+ flex-direction: column;
57
+ margin: var(--vx-space-stack-sm) 0 0;
58
+ padding: 0;
59
+ min-width: 0;
60
+ }
61
+
62
+ /*
63
+ * One row, one line, at the TAG tier (`controlHeightTag`, 20px at level 0) — the smallest control
64
+ * step basalt declares, and a token rather than a literal so the rows track the density knob with
65
+ * everything else. `justify-content: space-between` is what makes the pair read as a row without a
66
+ * grid: the label leads, the value trails, and neither needs a column to align against because
67
+ * every row in one card is the same box.
68
+ */
69
+ .breakdownRow {
70
+ display: flex;
71
+ align-items: center;
72
+ justify-content: space-between;
73
+ gap: var(--vx-space-control-gap);
74
+ min-height: var(--vx-space-control-height-tag);
75
+ min-width: 0;
76
+ }
77
+
78
+ .breakdownLabel {
79
+ overflow: hidden;
80
+ text-overflow: ellipsis;
81
+ white-space: nowrap;
82
+ font-size: var(--vx-text-sm);
83
+ color: var(--vx-muted);
84
+ }
85
+
86
+ /* Mono and ink — a breakdown value is a number, and it is the half of the row worth reading. Never
87
+ * shrinks: the LABEL is the prose half and the one that may ellipsize. */
88
+ .breakdownValue {
89
+ flex-shrink: 0;
90
+ margin: 0;
91
+ font-family: var(--basalt-font-mono);
92
+ font-size: var(--vx-text-sm);
93
+ font-weight: 500;
94
+ color: var(--vx-ink);
95
+ }
96
+
97
+ /*
98
+ * A row past a threshold. Same vocabulary and the same per-scheme solids as the card's own tone rail
99
+ * (`stat-card.tsx`'s `VX.status[tone]`), so a row saying `bad` and a rail saying `bad` are one claim
100
+ * at two scales. Colour is not the only carrier at the CARD level (the rail ships a
101
+ * `VisuallyHidden` verdict); at the ROW level the label is the carrier — a row reading
102
+ * `Paid · 1,204` states its own subject either way, and the tint only ranks it.
103
+ */
104
+ .breakdownRow[data-tone='good'] .breakdownValue {
105
+ color: var(--vx-status-good);
106
+ }
107
+
108
+ .breakdownRow[data-tone='warn'] .breakdownValue {
109
+ color: var(--vx-status-warn);
110
+ }
111
+
112
+ .breakdownRow[data-tone='bad'] .breakdownValue {
113
+ color: var(--vx-status-bad);
114
+ }
115
+
116
+ .sparklineBleed {
117
+ margin-top: auto;
118
+ margin-inline: calc(-1 * var(--mantine-spacing-sm));
119
+ margin-bottom: calc(-1 * var(--mantine-spacing-xs));
120
+ }
121
+
122
+ /* Asks for `StatCard`'s `SPARKLINE_RIGHT_WIDTH`/`_HEIGHT` (handed down as custom properties, so this
123
+ * rule and the `< sm` reset below can both reach them) and shrinks below the width before the hero
124
+ * row does — see the `.header` note above. `min-width: 0` is what lets it. */
125
+ .sparklineRight {
126
+ display: flex;
127
+ flex: 0 1 var(--basalt-stat-sparkline-w, 4.5rem);
128
+ min-width: 0;
129
+ height: var(--basalt-stat-sparkline-h, 1.625rem);
130
+ align-items: flex-end;
131
+ overflow: hidden;
132
+ }
133
+
134
+ @media (max-width: 47.99375em) {
135
+ .body[data-placement='right'] {
136
+ flex-direction: column;
137
+ align-items: stretch;
138
+ }
139
+
140
+ .body[data-placement='right'] .header {
141
+ flex: initial;
142
+ }
143
+
144
+ /* The row became a COLUMN, so `flex-basis` is now the main-axis HEIGHT — the 72px width would
145
+ * become a 72px-tall box around 26px of bars. `flex: none` + the height keeps the bled trend the
146
+ * same 26px it is beside a hero row. */
147
+ .body[data-placement='right'] .sparklineRight {
148
+ flex: none;
149
+ margin-top: auto;
150
+ margin-inline: calc(-1 * var(--mantine-spacing-sm));
151
+ margin-bottom: calc(-1 * var(--mantine-spacing-xs));
152
+ }
153
+ }
@@ -0,0 +1,15 @@
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.
4
+ */
5
+ declare const classes: {
6
+ readonly body: string
7
+ readonly header: string
8
+ readonly breakdown: string
9
+ readonly breakdownRow: string
10
+ readonly breakdownLabel: string
11
+ readonly breakdownValue: string
12
+ readonly sparklineBleed: string
13
+ readonly sparklineRight: string
14
+ }
15
+ export default classes
@@ -24,16 +24,16 @@ declare module '@tanstack/react-table' {
24
24
  numeral?: boolean;
25
25
  }
26
26
  }
27
- /** A single selectable option inside a {@link DataTableFacet}'s Select/MultiSelect. */
27
+ /** A single selectable option inside a {@link DataTableFacet}'s `EnumFilter`/`MultiSelectFilter` pill. */
28
28
  export type DataTableFacetOption = {
29
29
  /** The raw filter value, compared against the column's stringified cell value. */
30
30
  value: string;
31
- /** Label shown in the Select/MultiSelect dropdown. */
31
+ /** Label shown in the pill's popover. */
32
32
  label: string;
33
33
  };
34
34
  /**
35
- * Declares one faceted column filter, rendered as a Mantine Select (or MultiSelect when
36
- * `multiple` is set) inside the toolbar.
35
+ * Declares one faceted column filter, rendered as an `EnumFilter` pill (or `MultiSelectFilter`
36
+ * when `multiple` is set) inside a `FilterSet` in the toolbar (`docs/CONTROLS-SPEC.md` §3).
37
37
  *
38
38
  * @example
39
39
  * const facets: DataTableFacet[] = [
@@ -45,11 +45,11 @@ export type DataTableFacetOption = {
45
45
  export type DataTableFacet = {
46
46
  /** The TanStack column id — the column's manual `id`, or its `accessorKey` string. */
47
47
  columnId: string;
48
- /** Label shown as the Select/MultiSelect placeholder. */
48
+ /** The pill's label — read at rest (single-select) and as the `Filters`/count fallback (multi). */
49
49
  label: string;
50
50
  /** Selectable options for this facet. */
51
51
  options: DataTableFacetOption[];
52
- /** Render a MultiSelect (any-of match) instead of a single Select (exact match). @default false */
52
+ /** Render a `MultiSelectFilter` (any-of match) instead of an `EnumFilter` (exact match). @default false */
53
53
  multiple?: boolean;
54
54
  };
55
55
  /**
@@ -66,6 +66,16 @@ export type DataTableFacet = {
66
66
  * }
67
67
  */
68
68
  export type BasaltDataTableProps<T> = {
69
+ /**
70
+ * Optional heading rendered above the toolbar via `WidgetHeader tier="widget"`. `count` always
71
+ * reads `table.getRowCount()` (C11) — never a raw `data.length` — so it tracks the row model
72
+ * (post-filter/-pagination) rather than the unfiltered input.
73
+ */
74
+ title?: string;
75
+ /** Optional leading icon, forwarded to `WidgetHeader`. */
76
+ icon?: ReactNode;
77
+ /** Optional muted line rendered below the title row. */
78
+ subtitle?: string;
69
79
  /** Row data array. */
70
80
  data: T[];
71
81
  /**
@@ -162,9 +172,9 @@ export type BasaltDataTableProps<T> = {
162
172
  /** Called whenever the internal global filter value changes. */
163
173
  onGlobalFilterChange?: (value: string) => void;
164
174
  /**
165
- * Faceted column filters, rendered in the toolbar as Mantine Select/MultiSelect controls wired
166
- * to TanStack's per-column `columnFilters` state. The toolbar renders whenever this array is
167
- * non-empty, `enableGlobalFilter` is set, or `toolbarActions` is passed.
175
+ * Faceted column filters, rendered in the toolbar as `EnumFilter`/`MultiSelectFilter` pills
176
+ * inside a `FilterSet`, wired to TanStack's per-column `columnFilters` state. The toolbar
177
+ * renders whenever this array is non-empty, `enableGlobalFilter` is set, or `actions` is passed.
168
178
  * @example
169
179
  * facets={[{ columnId: 'department', label: 'Department', options: departmentOptions }]}
170
180
  */
@@ -183,9 +193,10 @@ export type BasaltDataTableProps<T> = {
183
193
  manualFiltering?: boolean;
184
194
  /**
185
195
  * Right-aligned toolbar slot (e.g. an "Export" button). Renders the toolbar row even when no
186
- * search input or facets are configured.
196
+ * search input or facets are configured. Renamed from `toolbarActions` — the toolbar (search +
197
+ * facets + this slot) is wrapped in `CtlSlot` (C1/C5), so its controls resolve to the `ctl` tier.
187
198
  */
188
- toolbarActions?: ReactNode;
199
+ actions?: ReactNode;
189
200
  /**
190
201
  * Enables the bottom pagination bar ("Showing X–Y of N", rows-per-page `Select`, Mantine
191
202
  * `Pagination`) wired to TanStack's `pagination` state. Client-side by default — see
@@ -280,9 +291,20 @@ export type BasaltDataTableProps<T> = {
280
291
  /** Row separators. Forwarded to Mantine `Table`. @default true (Mantine's own default) */
281
292
  withRowBorders?: boolean;
282
293
  /**
283
- * Outer table border. Turn it OFF for a table that already sits inside a `Card`/`ChartCard`,
284
- * where the card owns the frame and a second one reads as a nested box.
285
- * @default true
294
+ * Outer table border — a full box around the table.
295
+ *
296
+ * **`false` by default since this minor** (it was `true`). Three separate faults, all visible on
297
+ * the playground's `Controls (mobile)` page at 390px: its TOP edge sat directly under the table's
298
+ * own `WidgetHeader`, separating a header from its own content; its BOTTOM edge landed on the last
299
+ * row's own hairline, two rules at zero distance; and its left/right edges carried no information
300
+ * at all on a table that fills the page (`docs/DESIGN-SPEC.md` §8 — a border is a layout divider,
301
+ * and there is nothing here to divide). The head-row rule and the between-row rules stay, so the
302
+ * table still reads as a table.
303
+ *
304
+ * Pass `true` for a table that genuinely needs a frame — a small table floating in whitespace
305
+ * beside other content, where the box IS the grouping.
306
+ *
307
+ * @default false
286
308
  */
287
309
  withTableBorder?: boolean;
288
310
  };
@@ -311,5 +333,5 @@ export type BasaltDataTableProps<T> = {
311
333
  * emptyState={<Text c="dimmed">No users found.</Text>}
312
334
  * />
313
335
  */
314
- export declare function BasaltDataTable<T>({ data, columns, enableSorting, manualSorting, striped, highlightOnHover, emptyState, isLoading, skeletonRows, initialSorting, onSortingChange, enableGlobalFilter, globalFilterPlaceholder, searchIcon, initialGlobalFilter, onGlobalFilterChange, facets, onColumnFiltersChange, manualFiltering, toolbarActions, enablePagination, pageSizeOptions, initialPagination, onPaginationChange, manualPagination, rowCount, pageCount, enablePinning, initialColumnPinning, maxHeight, minWidth, stickyHeader, stickyHeaderOffset, verticalSpacing, horizontalSpacing, withRowBorders, withTableBorder, }: BasaltDataTableProps<T>): import("react").JSX.Element;
336
+ export declare function BasaltDataTable<T>({ title, icon, subtitle, data, columns, enableSorting, manualSorting, striped, highlightOnHover, emptyState, isLoading, skeletonRows, initialSorting, onSortingChange, enableGlobalFilter, globalFilterPlaceholder, searchIcon, initialGlobalFilter, onGlobalFilterChange, facets, onColumnFiltersChange, manualFiltering, actions, enablePagination, pageSizeOptions, initialPagination, onPaginationChange, manualPagination, rowCount, pageCount, enablePinning, initialColumnPinning, maxHeight, minWidth, stickyHeader, stickyHeaderOffset, verticalSpacing, horizontalSpacing, withRowBorders, withTableBorder, }: BasaltDataTableProps<T>): import("react").JSX.Element;
315
337
  //# sourceMappingURL=data-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/data/data-table.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../../src/data/data-table.tsx"],"names":[],"mappings":"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"}