@nadicodeai/ui 12.1.101 → 12.1.103

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 (567) hide show
  1. package/dist/components/accordion.d.ts +38 -12
  2. package/dist/components/accordion.d.ts.map +1 -1
  3. package/dist/components/accordion.js +36 -15
  4. package/dist/components/account-menu.d.ts +18 -18
  5. package/dist/components/account-menu.d.ts.map +1 -1
  6. package/dist/components/account-menu.js +17 -13
  7. package/dist/components/action-menu.d.ts +20 -19
  8. package/dist/components/action-menu.d.ts.map +1 -1
  9. package/dist/components/action-menu.js +22 -15
  10. package/dist/components/action-status.d.ts +14 -10
  11. package/dist/components/action-status.d.ts.map +1 -1
  12. package/dist/components/action-status.js +14 -10
  13. package/dist/components/activity-calendar.d.ts +3 -1
  14. package/dist/components/activity-calendar.d.ts.map +1 -1
  15. package/dist/components/activity-calendar.js +16 -2
  16. package/dist/components/activity-feed.d.ts +2 -2
  17. package/dist/components/activity-feed.d.ts.map +1 -1
  18. package/dist/components/activity-feed.js +14 -5
  19. package/dist/components/agent-card.d.ts +11 -5
  20. package/dist/components/agent-card.d.ts.map +1 -1
  21. package/dist/components/agent-card.js +13 -7
  22. package/dist/components/agent-list-row.js +1 -1
  23. package/dist/components/agent-orb-appearance.d.ts +7 -1
  24. package/dist/components/agent-orb-appearance.d.ts.map +1 -1
  25. package/dist/components/agent-orb-appearance.js +26 -0
  26. package/dist/components/agent-profile.d.ts +8 -7
  27. package/dist/components/agent-profile.d.ts.map +1 -1
  28. package/dist/components/agent-profile.js +6 -6
  29. package/dist/components/alert-dialog.d.ts +25 -16
  30. package/dist/components/alert-dialog.d.ts.map +1 -1
  31. package/dist/components/alert-dialog.js +30 -18
  32. package/dist/components/alert.d.ts +1 -1
  33. package/dist/components/avatar.d.ts +83 -17
  34. package/dist/components/avatar.d.ts.map +1 -1
  35. package/dist/components/avatar.js +89 -23
  36. package/dist/components/badge.d.ts +59 -8
  37. package/dist/components/badge.d.ts.map +1 -1
  38. package/dist/components/badge.js +57 -14
  39. package/dist/components/breadcrumb.d.ts +18 -7
  40. package/dist/components/breadcrumb.d.ts.map +1 -1
  41. package/dist/components/breadcrumb.js +37 -13
  42. package/dist/components/button-group.d.ts +12 -15
  43. package/dist/components/button-group.d.ts.map +1 -1
  44. package/dist/components/button-group.js +13 -17
  45. package/dist/components/button.d.ts +126 -23
  46. package/dist/components/button.d.ts.map +1 -1
  47. package/dist/components/button.js +164 -39
  48. package/dist/components/calendar.d.ts +26 -15
  49. package/dist/components/calendar.d.ts.map +1 -1
  50. package/dist/components/calendar.js +60 -46
  51. package/dist/components/card-row.d.ts +13 -5
  52. package/dist/components/card-row.d.ts.map +1 -1
  53. package/dist/components/card-row.js +24 -10
  54. package/dist/components/card.d.ts +6 -12
  55. package/dist/components/card.d.ts.map +1 -1
  56. package/dist/components/card.js +11 -16
  57. package/dist/components/carousel.d.ts +3 -3
  58. package/dist/components/carousel.d.ts.map +1 -1
  59. package/dist/components/carousel.js +7 -7
  60. package/dist/components/catalog-drawer.d.ts +7 -7
  61. package/dist/components/catalog-drawer.d.ts.map +1 -1
  62. package/dist/components/catalog-drawer.js +6 -6
  63. package/dist/components/chart-area-stacked.d.ts +1 -1
  64. package/dist/components/chart-area-stacked.d.ts.map +1 -1
  65. package/dist/components/chart-area-stacked.js +4 -4
  66. package/dist/components/chart-axis.d.ts +14 -1
  67. package/dist/components/chart-axis.d.ts.map +1 -1
  68. package/dist/components/chart-axis.js +11 -1
  69. package/dist/components/chart-bar-horizontal.d.ts +2 -2
  70. package/dist/components/chart-bar-horizontal.d.ts.map +1 -1
  71. package/dist/components/chart-bar-horizontal.js +14 -5
  72. package/dist/components/chart-bar-multiple.d.ts +1 -1
  73. package/dist/components/chart-bar-multiple.d.ts.map +1 -1
  74. package/dist/components/chart-bar-multiple.js +3 -3
  75. package/dist/components/chart-bar-stacked.d.ts +1 -1
  76. package/dist/components/chart-bar-stacked.d.ts.map +1 -1
  77. package/dist/components/chart-bar-stacked.js +3 -3
  78. package/dist/components/chart-card.d.ts +17 -6
  79. package/dist/components/chart-card.d.ts.map +1 -1
  80. package/dist/components/chart-card.js +11 -4
  81. package/dist/components/chart-date-range-control.d.ts +18 -9
  82. package/dist/components/chart-date-range-control.d.ts.map +1 -1
  83. package/dist/components/chart-date-range-control.js +43 -47
  84. package/dist/components/chart-sparkline.d.ts +4 -3
  85. package/dist/components/chart-sparkline.d.ts.map +1 -1
  86. package/dist/components/chart-sparkline.js +6 -5
  87. package/dist/components/check-counts.d.ts +44 -0
  88. package/dist/components/check-counts.d.ts.map +1 -0
  89. package/dist/components/check-counts.js +51 -0
  90. package/dist/components/checkbox.d.ts +39 -11
  91. package/dist/components/checkbox.d.ts.map +1 -1
  92. package/dist/components/checkbox.js +38 -11
  93. package/dist/components/choicebox.d.ts +96 -0
  94. package/dist/components/choicebox.d.ts.map +1 -0
  95. package/dist/components/choicebox.js +113 -0
  96. package/dist/components/clearable-input.d.ts +57 -0
  97. package/dist/components/clearable-input.d.ts.map +1 -0
  98. package/dist/components/clearable-input.js +58 -0
  99. package/dist/components/code-block.d.ts +77 -17
  100. package/dist/components/code-block.d.ts.map +1 -1
  101. package/dist/components/code-block.js +85 -15
  102. package/dist/components/collapsible.d.ts +27 -10
  103. package/dist/components/collapsible.d.ts.map +1 -1
  104. package/dist/components/collapsible.js +24 -9
  105. package/dist/components/collection-filters.d.ts +3 -1
  106. package/dist/components/collection-filters.d.ts.map +1 -1
  107. package/dist/components/collection-filters.js +7 -9
  108. package/dist/components/collection-page.d.ts +31 -10
  109. package/dist/components/collection-page.d.ts.map +1 -1
  110. package/dist/components/collection-page.js +14 -13
  111. package/dist/components/collection-search.d.ts +32 -10
  112. package/dist/components/collection-search.d.ts.map +1 -1
  113. package/dist/components/collection-search.js +24 -13
  114. package/dist/components/collection-sort.d.ts.map +1 -1
  115. package/dist/components/collection-sort.js +2 -2
  116. package/dist/components/collection-toolbar.d.ts +5 -2
  117. package/dist/components/collection-toolbar.d.ts.map +1 -1
  118. package/dist/components/collection-toolbar.js +7 -4
  119. package/dist/components/combobox.d.ts +97 -22
  120. package/dist/components/combobox.d.ts.map +1 -1
  121. package/dist/components/combobox.js +80 -28
  122. package/dist/components/command.d.ts +34 -21
  123. package/dist/components/command.d.ts.map +1 -1
  124. package/dist/components/command.js +33 -25
  125. package/dist/components/confirm-dialog.d.ts +23 -6
  126. package/dist/components/confirm-dialog.d.ts.map +1 -1
  127. package/dist/components/confirm-dialog.js +32 -13
  128. package/dist/components/context-menu.d.ts +14 -10
  129. package/dist/components/context-menu.d.ts.map +1 -1
  130. package/dist/components/context-menu.js +17 -12
  131. package/dist/components/copy-button.d.ts +5 -2
  132. package/dist/components/copy-button.d.ts.map +1 -1
  133. package/dist/components/copy-button.js +16 -8
  134. package/dist/components/data-table.d.ts +120 -54
  135. package/dist/components/data-table.d.ts.map +1 -1
  136. package/dist/components/data-table.js +163 -92
  137. package/dist/components/desktop-shell.d.ts +4 -2
  138. package/dist/components/desktop-shell.d.ts.map +1 -1
  139. package/dist/components/desktop-shell.js +3 -3
  140. package/dist/components/dialog.d.ts +63 -24
  141. package/dist/components/dialog.d.ts.map +1 -1
  142. package/dist/components/dialog.js +52 -31
  143. package/dist/components/disclosure-row.d.ts +1 -2
  144. package/dist/components/disclosure-row.d.ts.map +1 -1
  145. package/dist/components/disclosure-row.js +1 -2
  146. package/dist/components/disclosure.d.ts +1 -1
  147. package/dist/components/disclosure.js +1 -1
  148. package/dist/components/drawer.d.ts +33 -12
  149. package/dist/components/drawer.d.ts.map +1 -1
  150. package/dist/components/drawer.js +47 -35
  151. package/dist/components/dropdown-menu.d.ts +59 -14
  152. package/dist/components/dropdown-menu.d.ts.map +1 -1
  153. package/dist/components/dropdown-menu.js +58 -26
  154. package/dist/components/empty-state.d.ts +35 -12
  155. package/dist/components/empty-state.d.ts.map +1 -1
  156. package/dist/components/empty-state.js +35 -17
  157. package/dist/components/entry-scene.d.ts +4 -4
  158. package/dist/components/entry-scene.d.ts.map +1 -1
  159. package/dist/components/entry-scene.js +2 -2
  160. package/dist/components/field.d.ts +44 -14
  161. package/dist/components/field.d.ts.map +1 -1
  162. package/dist/components/field.js +49 -20
  163. package/dist/components/file-diff.d.ts.map +1 -1
  164. package/dist/components/file-diff.js +3 -4
  165. package/dist/components/form-dialog.d.ts +7 -7
  166. package/dist/components/form-dialog.d.ts.map +1 -1
  167. package/dist/components/form-dialog.js +13 -11
  168. package/dist/components/form-drawer.d.ts +10 -7
  169. package/dist/components/form-drawer.d.ts.map +1 -1
  170. package/dist/components/form-drawer.js +11 -10
  171. package/dist/components/gauge.d.ts +64 -0
  172. package/dist/components/gauge.d.ts.map +1 -0
  173. package/dist/components/gauge.js +73 -0
  174. package/dist/components/hover-card.d.ts +72 -14
  175. package/dist/components/hover-card.d.ts.map +1 -1
  176. package/dist/components/hover-card.js +51 -17
  177. package/dist/components/identity-mark.d.ts +8 -1
  178. package/dist/components/identity-mark.d.ts.map +1 -1
  179. package/dist/components/identity-mark.js +31 -5
  180. package/dist/components/input-group.d.ts +44 -21
  181. package/dist/components/input-group.d.ts.map +1 -1
  182. package/dist/components/input-group.js +74 -27
  183. package/dist/components/input.d.ts +64 -12
  184. package/dist/components/input.d.ts.map +1 -1
  185. package/dist/components/input.js +51 -15
  186. package/dist/components/item.d.ts +37 -15
  187. package/dist/components/item.d.ts.map +1 -1
  188. package/dist/components/item.js +41 -22
  189. package/dist/components/kbd.d.ts +49 -13
  190. package/dist/components/kbd.d.ts.map +1 -1
  191. package/dist/components/kbd.js +115 -16
  192. package/dist/components/kpi-card.d.ts +12 -4
  193. package/dist/components/kpi-card.d.ts.map +1 -1
  194. package/dist/components/kpi-card.js +13 -4
  195. package/dist/components/label.d.ts +17 -10
  196. package/dist/components/label.d.ts.map +1 -1
  197. package/dist/components/label.js +18 -11
  198. package/dist/components/library-shelf.d.ts +6 -6
  199. package/dist/components/library-shelf.d.ts.map +1 -1
  200. package/dist/components/library-shelf.js +5 -5
  201. package/dist/components/load-more-button.d.ts +35 -0
  202. package/dist/components/load-more-button.d.ts.map +1 -0
  203. package/dist/components/load-more-button.js +26 -0
  204. package/dist/components/menu-choice-row.d.ts +6 -8
  205. package/dist/components/menu-choice-row.d.ts.map +1 -1
  206. package/dist/components/menu-choice-row.js +8 -8
  207. package/dist/components/message-notice.d.ts +8 -13
  208. package/dist/components/message-notice.d.ts.map +1 -1
  209. package/dist/components/message-notice.js +25 -22
  210. package/dist/components/middle-truncate.d.ts +33 -0
  211. package/dist/components/middle-truncate.d.ts.map +1 -0
  212. package/dist/components/middle-truncate.js +72 -0
  213. package/dist/components/multi-select.d.ts +94 -0
  214. package/dist/components/multi-select.d.ts.map +1 -0
  215. package/dist/components/multi-select.js +132 -0
  216. package/dist/components/native-select.d.ts +37 -13
  217. package/dist/components/native-select.d.ts.map +1 -1
  218. package/dist/components/native-select.js +27 -11
  219. package/dist/components/notice-banner.d.ts +17 -10
  220. package/dist/components/notice-banner.d.ts.map +1 -1
  221. package/dist/components/notice-banner.js +12 -11
  222. package/dist/components/numbered-steps.d.ts +10 -4
  223. package/dist/components/numbered-steps.d.ts.map +1 -1
  224. package/dist/components/numbered-steps.js +9 -7
  225. package/dist/components/object-page.d.ts +40 -14
  226. package/dist/components/object-page.d.ts.map +1 -1
  227. package/dist/components/object-page.js +12 -10
  228. package/dist/components/object-workspace.d.ts +29 -10
  229. package/dist/components/object-workspace.d.ts.map +1 -1
  230. package/dist/components/object-workspace.js +18 -8
  231. package/dist/components/overview-page.d.ts +2 -2
  232. package/dist/components/overview-page.d.ts.map +1 -1
  233. package/dist/components/overview-page.js +8 -7
  234. package/dist/components/page-actions.d.ts +28 -8
  235. package/dist/components/page-actions.d.ts.map +1 -1
  236. package/dist/components/page-actions.js +22 -25
  237. package/dist/components/page-header.d.ts +11 -4
  238. package/dist/components/page-header.d.ts.map +1 -1
  239. package/dist/components/page-header.js +10 -5
  240. package/dist/components/pending-label.d.ts +6 -5
  241. package/dist/components/pending-label.d.ts.map +1 -1
  242. package/dist/components/pending-label.js +14 -6
  243. package/dist/components/picture-label.d.ts +2 -2
  244. package/dist/components/picture-label.d.ts.map +1 -1
  245. package/dist/components/picture-label.js +3 -3
  246. package/dist/components/portal-sidebar-frame.d.ts +9 -21
  247. package/dist/components/portal-sidebar-frame.d.ts.map +1 -1
  248. package/dist/components/portal-sidebar-frame.js +13 -27
  249. package/dist/components/progress-checklist.d.ts +46 -0
  250. package/dist/components/progress-checklist.d.ts.map +1 -0
  251. package/dist/components/progress-checklist.js +46 -0
  252. package/dist/components/progress.d.ts +48 -8
  253. package/dist/components/progress.d.ts.map +1 -1
  254. package/dist/components/progress.js +92 -16
  255. package/dist/components/prose.d.ts +19 -0
  256. package/dist/components/prose.d.ts.map +1 -0
  257. package/dist/components/prose.js +29 -0
  258. package/dist/components/radio-group.d.ts +51 -12
  259. package/dist/components/radio-group.d.ts.map +1 -1
  260. package/dist/components/radio-group.js +42 -12
  261. package/dist/components/reading-column.js +1 -1
  262. package/dist/components/record-identity.d.ts +6 -5
  263. package/dist/components/record-identity.d.ts.map +1 -1
  264. package/dist/components/record-identity.js +12 -3
  265. package/dist/components/record-list.d.ts +117 -27
  266. package/dist/components/record-list.d.ts.map +1 -1
  267. package/dist/components/record-list.js +185 -55
  268. package/dist/components/record-time.d.ts +20 -7
  269. package/dist/components/record-time.d.ts.map +1 -1
  270. package/dist/components/record-time.js +38 -19
  271. package/dist/components/resizable.d.ts +7 -5
  272. package/dist/components/resizable.d.ts.map +1 -1
  273. package/dist/components/resizable.js +6 -6
  274. package/dist/components/scope-switcher.d.ts +2 -0
  275. package/dist/components/scope-switcher.d.ts.map +1 -1
  276. package/dist/components/scope-switcher.js +2 -2
  277. package/dist/components/scroll-area.d.ts +47 -11
  278. package/dist/components/scroll-area.d.ts.map +1 -1
  279. package/dist/components/scroll-area.js +72 -14
  280. package/dist/components/segmented-control.d.ts +82 -0
  281. package/dist/components/segmented-control.d.ts.map +1 -0
  282. package/dist/components/segmented-control.js +90 -0
  283. package/dist/components/select.d.ts +55 -15
  284. package/dist/components/select.d.ts.map +1 -1
  285. package/dist/components/select.js +62 -19
  286. package/dist/components/separator.d.ts +12 -5
  287. package/dist/components/separator.d.ts.map +1 -1
  288. package/dist/components/separator.js +11 -6
  289. package/dist/components/settings-facts.d.ts +34 -14
  290. package/dist/components/settings-facts.d.ts.map +1 -1
  291. package/dist/components/settings-facts.js +21 -12
  292. package/dist/components/settings-page.d.ts +4 -4
  293. package/dist/components/settings-page.js +5 -5
  294. package/dist/components/settings-section.d.ts +160 -34
  295. package/dist/components/settings-section.d.ts.map +1 -1
  296. package/dist/components/settings-section.js +92 -39
  297. package/dist/components/sheet.d.ts +47 -16
  298. package/dist/components/sheet.d.ts.map +1 -1
  299. package/dist/components/sheet.js +40 -19
  300. package/dist/components/sidebar-sections.d.ts +16 -12
  301. package/dist/components/sidebar-sections.d.ts.map +1 -1
  302. package/dist/components/sidebar-sections.js +30 -15
  303. package/dist/components/sidebar.d.ts +117 -21
  304. package/dist/components/sidebar.d.ts.map +1 -1
  305. package/dist/components/sidebar.js +180 -55
  306. package/dist/components/skeleton.d.ts +54 -8
  307. package/dist/components/skeleton.d.ts.map +1 -1
  308. package/dist/components/skeleton.js +44 -9
  309. package/dist/components/slider.d.ts +53 -11
  310. package/dist/components/slider.d.ts.map +1 -1
  311. package/dist/components/slider.js +71 -17
  312. package/dist/components/snippet.d.ts +57 -0
  313. package/dist/components/snippet.d.ts.map +1 -0
  314. package/dist/components/snippet.js +60 -0
  315. package/dist/components/sonner.d.ts +13 -14
  316. package/dist/components/sonner.d.ts.map +1 -1
  317. package/dist/components/sonner.js +25 -22
  318. package/dist/components/status-badge.d.ts +37 -11
  319. package/dist/components/status-badge.d.ts.map +1 -1
  320. package/dist/components/status-badge.js +63 -15
  321. package/dist/components/status-dot.d.ts +42 -11
  322. package/dist/components/status-dot.d.ts.map +1 -1
  323. package/dist/components/status-dot.js +40 -11
  324. package/dist/components/switch.d.ts +43 -12
  325. package/dist/components/switch.d.ts.map +1 -1
  326. package/dist/components/switch.js +42 -12
  327. package/dist/components/table-card.d.ts +21 -12
  328. package/dist/components/table-card.d.ts.map +1 -1
  329. package/dist/components/table-card.js +17 -9
  330. package/dist/components/table-layouts.d.ts +40 -8
  331. package/dist/components/table-layouts.d.ts.map +1 -1
  332. package/dist/components/table-layouts.js +52 -8
  333. package/dist/components/table-value.d.ts +4 -3
  334. package/dist/components/table-value.d.ts.map +1 -1
  335. package/dist/components/table-value.js +6 -5
  336. package/dist/components/table.d.ts +62 -25
  337. package/dist/components/table.d.ts.map +1 -1
  338. package/dist/components/table.js +62 -26
  339. package/dist/components/tabs.d.ts +86 -17
  340. package/dist/components/tabs.d.ts.map +1 -1
  341. package/dist/components/tabs.js +93 -22
  342. package/dist/components/text-link.d.ts +4 -1
  343. package/dist/components/text-link.d.ts.map +1 -1
  344. package/dist/components/text-link.js +4 -1
  345. package/dist/components/text-with-copy-button.d.ts +30 -0
  346. package/dist/components/text-with-copy-button.d.ts.map +1 -0
  347. package/dist/components/text-with-copy-button.js +32 -0
  348. package/dist/components/textarea.d.ts +40 -10
  349. package/dist/components/textarea.d.ts.map +1 -1
  350. package/dist/components/textarea.js +50 -11
  351. package/dist/components/theme-mode-switcher.d.ts +20 -3
  352. package/dist/components/theme-mode-switcher.d.ts.map +1 -1
  353. package/dist/components/theme-mode-switcher.js +23 -6
  354. package/dist/components/toggle-group.d.ts +28 -8
  355. package/dist/components/toggle-group.d.ts.map +1 -1
  356. package/dist/components/toggle-group.js +12 -6
  357. package/dist/components/toggle.d.ts +6 -3
  358. package/dist/components/toggle.d.ts.map +1 -1
  359. package/dist/components/toggle.js +10 -7
  360. package/dist/components/tooltip.d.ts +43 -12
  361. package/dist/components/tooltip.d.ts.map +1 -1
  362. package/dist/components/tooltip.js +45 -16
  363. package/dist/components/trend-badge.js +1 -1
  364. package/dist/components/update-card.js +1 -1
  365. package/dist/eslint/index.js +82 -0
  366. package/dist/eslint/rules/badge-is-static-label.js +93 -0
  367. package/dist/eslint/rules/button-icon-slot.js +102 -0
  368. package/dist/eslint/rules/button-link-for-navigation.js +146 -0
  369. package/dist/eslint/rules/button-no-aria-label-with-text.js +75 -0
  370. package/dist/eslint/rules/button-type-roles-only-in-buttons.js +83 -0
  371. package/dist/eslint/rules/choice-control-has-a-name.js +98 -0
  372. package/dist/eslint/rules/choice-group-in-fieldset.js +86 -0
  373. package/dist/eslint/rules/command-shortcut-single-owner.js +118 -0
  374. package/dist/eslint/rules/confirm-dialog-words.js +63 -0
  375. package/dist/eslint/rules/data-table-one-unsized-column.js +96 -0
  376. package/dist/eslint/rules/destructive-action-placement.js +69 -0
  377. package/dist/eslint/rules/disabled-choice-says-why.js +71 -0
  378. package/dist/eslint/rules/ellipsis-opens-a-dialog.js +110 -0
  379. package/dist/eslint/rules/input-group-owners.js +155 -0
  380. package/dist/eslint/rules/kbd-children-no-modifier-text.js +128 -0
  381. package/dist/eslint/rules/literal-text.js +41 -0
  382. package/dist/eslint/rules/middle-truncate-placement.js +69 -0
  383. package/dist/eslint/rules/no-bare-button-label.js +55 -0
  384. package/dist/eslint/rules/no-control-in-read-only-surface.js +106 -0
  385. package/dist/eslint/rules/no-hand-built-busy.js +104 -0
  386. package/dist/eslint/rules/no-hand-built-theme-picker.js +144 -0
  387. package/dist/eslint/rules/no-hand-built-tile.js +41 -0
  388. package/dist/eslint/rules/no-hand-formatted-date.js +87 -0
  389. package/dist/eslint/rules/no-hand-stacked-avatars.js +67 -0
  390. package/dist/eslint/rules/no-nested-collapse.js +60 -0
  391. package/dist/eslint/rules/no-search-in-form.js +47 -0
  392. package/dist/eslint/rules/no-shadcn-appearance-override.js +2 -16
  393. package/dist/eslint/rules/no-shell-prompt-in-snippet.js +74 -0
  394. package/dist/eslint/rules/no-stock-error-words.js +56 -0
  395. package/dist/eslint/rules/no-tooltip-around-labelled-field.js +72 -0
  396. package/dist/eslint/rules/no-weight-class-on-strong-in-type-role.js +57 -0
  397. package/dist/eslint/rules/one-submenu-level.js +43 -0
  398. package/dist/eslint/rules/one-toast-per-flow.js +91 -0
  399. package/dist/eslint/rules/option-count.js +167 -0
  400. package/dist/eslint/rules/page-command-link-not-render.js +43 -0
  401. package/dist/eslint/rules/progress-needs-name.js +57 -0
  402. package/dist/eslint/rules/settings-limit-in-footer.js +94 -0
  403. package/dist/eslint/rules/skeleton-in-region.js +80 -0
  404. package/dist/eslint/rules/sortable-heading-uses-sort.js +79 -0
  405. package/dist/eslint/rules/table-cell-inset-owner.js +107 -0
  406. package/dist/eslint/rules/tabs-selection-is-controlled.js +47 -0
  407. package/dist/eslint/rules/tooltip-only-arrow.js +38 -0
  408. package/dist/eslint/rules/tooltip-trigger-accessible-name.js +114 -0
  409. package/dist/eslint/strict-design-system.js +21 -7
  410. package/dist/index.d.ts +13 -13
  411. package/dist/index.d.ts.map +1 -1
  412. package/dist/index.js +12 -13
  413. package/dist/internal/assistant-ui/attachment.d.ts.map +1 -1
  414. package/dist/internal/assistant-ui/attachment.js +2 -2
  415. package/dist/internal/assistant-ui/reasoning.d.ts +1 -1
  416. package/dist/internal/assistant-ui/reasoning.d.ts.map +1 -1
  417. package/dist/internal/assistant-ui/tool-fallback.js +1 -1
  418. package/dist/internal/assistant-ui/tool-group.d.ts +1 -1
  419. package/dist/internal/assistant-ui/tool-group.d.ts.map +1 -1
  420. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts +2 -3
  421. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts.map +1 -1
  422. package/dist/internal/assistant-ui/tooltip-icon-button.js +1 -1
  423. package/dist/internal/catalog-list.js +2 -2
  424. package/dist/internal/collection-note.d.ts +23 -0
  425. package/dist/internal/collection-note.d.ts.map +1 -0
  426. package/dist/internal/collection-note.js +17 -0
  427. package/dist/internal/collection-rail.d.ts +57 -0
  428. package/dist/internal/collection-rail.d.ts.map +1 -0
  429. package/dist/internal/collection-rail.js +33 -0
  430. package/dist/internal/company-logo.d.ts +18 -0
  431. package/dist/internal/company-logo.d.ts.map +1 -0
  432. package/dist/internal/company-logo.js +14 -0
  433. package/dist/internal/control-name.d.ts +12 -0
  434. package/dist/internal/control-name.d.ts.map +1 -0
  435. package/dist/internal/control-name.js +1 -0
  436. package/dist/internal/diff-line.d.ts +9 -0
  437. package/dist/internal/diff-line.d.ts.map +1 -0
  438. package/dist/internal/diff-line.js +8 -0
  439. package/dist/internal/empty.d.ts +8 -4
  440. package/dist/internal/empty.d.ts.map +1 -1
  441. package/dist/internal/empty.js +14 -8
  442. package/dist/internal/field-frame.d.ts +33 -0
  443. package/dist/internal/field-frame.d.ts.map +1 -0
  444. package/dist/internal/field-frame.js +20 -0
  445. package/dist/internal/final-focus.d.ts +8 -0
  446. package/dist/internal/final-focus.d.ts.map +1 -0
  447. package/dist/internal/final-focus.js +10 -0
  448. package/dist/internal/footer-strip.d.ts.map +1 -1
  449. package/dist/internal/footer-strip.js +3 -1
  450. package/dist/internal/form-submit.d.ts +9 -5
  451. package/dist/internal/form-submit.d.ts.map +1 -1
  452. package/dist/internal/form-submit.js +31 -2
  453. package/dist/internal/input-box.d.ts +26 -0
  454. package/dist/internal/input-box.d.ts.map +1 -0
  455. package/dist/internal/input-box.js +59 -0
  456. package/dist/internal/menu-surface.d.ts +10 -3
  457. package/dist/internal/menu-surface.d.ts.map +1 -1
  458. package/dist/internal/menu-surface.js +10 -3
  459. package/dist/internal/notice.d.ts +25 -0
  460. package/dist/internal/notice.d.ts.map +1 -0
  461. package/dist/internal/notice.js +33 -0
  462. package/dist/internal/overlay-stem.d.ts +5 -0
  463. package/dist/internal/overlay-stem.d.ts.map +1 -0
  464. package/dist/internal/overlay-stem.js +7 -0
  465. package/dist/internal/phone-sheet.d.ts +4 -0
  466. package/dist/internal/phone-sheet.d.ts.map +1 -0
  467. package/dist/internal/phone-sheet.js +2 -0
  468. package/dist/internal/present-content.d.ts +3 -0
  469. package/dist/internal/present-content.d.ts.map +1 -0
  470. package/dist/internal/present-content.js +1 -0
  471. package/dist/internal/record-menu-items.d.ts +4 -3
  472. package/dist/internal/record-menu-items.d.ts.map +1 -1
  473. package/dist/internal/record-menu-items.js +21 -6
  474. package/dist/internal/settings-save.d.ts +9 -2
  475. package/dist/internal/settings-save.d.ts.map +1 -1
  476. package/dist/internal/settings-save.js +9 -6
  477. package/dist/internal/table-compact-line.d.ts +38 -0
  478. package/dist/internal/table-compact-line.d.ts.map +1 -0
  479. package/dist/internal/table-compact-line.js +35 -0
  480. package/dist/internal/title-when-cut.d.ts +8 -0
  481. package/dist/internal/title-when-cut.d.ts.map +1 -0
  482. package/dist/internal/title-when-cut.js +22 -0
  483. package/dist/internal/unsaved-guard.d.ts +18 -0
  484. package/dist/internal/unsaved-guard.d.ts.map +1 -0
  485. package/dist/internal/unsaved-guard.js +31 -0
  486. package/dist/lib/merge-tokens.generated.js +2 -2
  487. package/dist/showcase/foundations.d.ts.map +1 -1
  488. package/dist/showcase/foundations.js +10 -2
  489. package/dist/showcase/specimens/actions.d.ts +2 -0
  490. package/dist/showcase/specimens/actions.d.ts.map +1 -1
  491. package/dist/showcase/specimens/actions.js +30 -5
  492. package/dist/showcase/specimens/charts.d.ts.map +1 -1
  493. package/dist/showcase/specimens/charts.js +22 -13
  494. package/dist/showcase/specimens/choices.d.ts +14 -3
  495. package/dist/showcase/specimens/choices.d.ts.map +1 -1
  496. package/dist/showcase/specimens/choices.js +93 -13
  497. package/dist/showcase/specimens/compositions.d.ts.map +1 -1
  498. package/dist/showcase/specimens/compositions.js +136 -23
  499. package/dist/showcase/specimens/data.d.ts +12 -7
  500. package/dist/showcase/specimens/data.d.ts.map +1 -1
  501. package/dist/showcase/specimens/data.js +139 -35
  502. package/dist/showcase/specimens/feedback.d.ts +2 -0
  503. package/dist/showcase/specimens/feedback.d.ts.map +1 -1
  504. package/dist/showcase/specimens/feedback.js +39 -15
  505. package/dist/showcase/specimens/index.d.ts +20 -12
  506. package/dist/showcase/specimens/index.d.ts.map +1 -1
  507. package/dist/showcase/specimens/inputs.d.ts +4 -2
  508. package/dist/showcase/specimens/inputs.d.ts.map +1 -1
  509. package/dist/showcase/specimens/inputs.js +62 -19
  510. package/dist/showcase/specimens/menus.d.ts +0 -1
  511. package/dist/showcase/specimens/menus.d.ts.map +1 -1
  512. package/dist/showcase/specimens/menus.js +47 -18
  513. package/dist/showcase/specimens/navigation.d.ts +6 -4
  514. package/dist/showcase/specimens/navigation.d.ts.map +1 -1
  515. package/dist/showcase/specimens/navigation.js +61 -32
  516. package/dist/showcase/specimens/other.d.ts +1 -3
  517. package/dist/showcase/specimens/other.d.ts.map +1 -1
  518. package/dist/showcase/specimens/other.js +17 -13
  519. package/dist/showcase/specimens/status.d.ts +4 -1
  520. package/dist/showcase/specimens/status.d.ts.map +1 -1
  521. package/dist/showcase/specimens/status.js +64 -11
  522. package/dist/showcase/usage.generated.d.ts +1 -1
  523. package/dist/showcase/usage.generated.d.ts.map +1 -1
  524. package/dist/showcase/usage.generated.js +637 -549
  525. package/dist/standalone/index.js +1 -1
  526. package/dist/styles/components.css +13 -13
  527. package/dist/styles/globals.css +25 -0
  528. package/package.json +2 -3
  529. package/dist/components/approval-row.d.ts +0 -34
  530. package/dist/components/approval-row.d.ts.map +0 -1
  531. package/dist/components/approval-row.js +0 -27
  532. package/dist/components/channel-view.d.ts +0 -112
  533. package/dist/components/channel-view.d.ts.map +0 -1
  534. package/dist/components/channel-view.js +0 -84
  535. package/dist/components/dashboard-shell.d.ts +0 -51
  536. package/dist/components/dashboard-shell.d.ts.map +0 -1
  537. package/dist/components/dashboard-shell.js +0 -89
  538. package/dist/components/direction.d.ts +0 -2
  539. package/dist/components/direction.d.ts.map +0 -1
  540. package/dist/components/direction.js +0 -1
  541. package/dist/components/expandable-block.d.ts +0 -20
  542. package/dist/components/expandable-block.d.ts.map +0 -1
  543. package/dist/components/expandable-block.js +0 -32
  544. package/dist/components/form.d.ts +0 -42
  545. package/dist/components/form.d.ts.map +0 -1
  546. package/dist/components/form.js +0 -91
  547. package/dist/components/label-system.d.ts +0 -17
  548. package/dist/components/label-system.d.ts.map +0 -1
  549. package/dist/components/label-system.js +0 -21
  550. package/dist/components/memory-item.d.ts +0 -21
  551. package/dist/components/memory-item.d.ts.map +0 -1
  552. package/dist/components/memory-item.js +0 -18
  553. package/dist/components/menubar.d.ts +0 -43
  554. package/dist/components/menubar.d.ts.map +0 -1
  555. package/dist/components/menubar.js +0 -69
  556. package/dist/components/navigation-menu.d.ts +0 -26
  557. package/dist/components/navigation-menu.d.ts.map +0 -1
  558. package/dist/components/navigation-menu.js +0 -45
  559. package/dist/components/pagination.d.ts +0 -33
  560. package/dist/components/pagination.d.ts.map +0 -1
  561. package/dist/components/pagination.js +0 -41
  562. package/dist/components/plugin-slot-boundary.d.ts +0 -42
  563. package/dist/components/plugin-slot-boundary.d.ts.map +0 -1
  564. package/dist/components/plugin-slot-boundary.js +0 -41
  565. package/dist/components/status-row.d.ts +0 -32
  566. package/dist/components/status-row.d.ts.map +0 -1
  567. package/dist/components/status-row.js +0 -35
@@ -3,20 +3,14 @@ import { useRender } from "@base-ui/react/use-render";
3
3
  type CardSurface = "plain" | "resting" | "raised" | "outlined";
4
4
  type CardVariant = "default" | "interactive" | "link";
5
5
  /**
6
- * A resting surface that holds one thing: a header, content and a recessed footer.
6
+ * The surface of every card; on its own only a container inside a composition.
7
7
  *
8
8
  * @family Data
9
- * @when A bounded piece of a page that stands on its own: a settings section, a KPI, a chart, a
10
- * table. Usually reached through the composition that owns that job.
11
- * @instead A page's own header is never in a card. A row of a list is `Item`. A plane of brand
12
- * colour is `BrandField`.
13
- * @behaviour The resting material: 6 px corners and the rest shadow, no border of its own.
14
- * `CardHeader` lays out title, description and one `CardAction`; `CardFooter` is the recessed strip
15
- * behind one seam. `size="sm"` for a compact card in a side column.
16
- * @words The title is a noun phrase naming what the card holds; the description one sentence, only
17
- * when it adds something.
18
- * @access A plain container; give it `render={<section />}` with a heading when it is a region of
19
- * the page.
9
+ * @when "For in-product cards and dashboard tiles, use `Card`; Book is too decorative for repeated UI rows." (https://vercel.com/geist/book) Ours: only inside a composition that owns the job: the object card of an `ObjectPage`, the setting card of a `SettingsSection`, a KPI, a chart, a table. A new kind of card is a new composition, never a `Card` assembled at a call site.
10
+ * @instead "Groups related form controls inside a bordered card with optional footer actions." (https://vercel.com/geist/fieldset) Ours: that card, a title and description, one control and a footer with help at the start and one action at the end, is `SettingsSection`. An object's card (a header bar with its name and commands, a body of facts, rows that open, a footer hint with one link elsewhere) is `ObjectPage`. The page's title row is never in a card. A row of a list is `Item`. A plane of brand colour is `BrandField`.
11
+ * @behaviour "One Note per concept." (https://vercel.com/geist/note) "Stacking three Notes on a card means the page architecture, not the Note copy, is wrong." (https://vercel.com/geist/note) "Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary." (https://vercel.com/geist/error) Ours: the corner and shadow come with `surface`: a raised card takes the larger corner. Never set a corner at the call site. `CardHeader` lays out title, description and one `CardAction`, which stays at the title's right at every width when it is one control (a button, a badge, the three dots) and moves under the description in a header narrower than 28rem when it holds several; `CardFooter` is the recessed strip behind one seam: on the left one short muted line (a hint, a constraint, the plan a feature needs), on the right at most one button or link. It is 56 px high whether or not it holds a button, and as high as its lines in a `size="sm"` card, the compact card of a side column or a figure. The two kinds differ in what their header and footer hold: an object card's header holds the object's commands and its footer only a link, so it never saves; a setting card's header holds a title, a description and at most a switch that applies on change, and its footer holds the Save. A card is neutral; colour enters only through a status inside it or a section's `tone`.
12
+ * @words The title is a noun phrase naming what the card holds; the description one sentence directly under it, only when it adds something.
13
+ * @access A plain container; give it `render={<section />}` with a heading when it is a region of the page.
20
14
  */
21
15
  declare function Card({ className, render, size, surface, variant, ...props }: useRender.ComponentProps<"div"> & {
22
16
  size?: "default" | "sm";
@@ -1 +1 @@
1
- {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/components/card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAItD,KAAK,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC/D,KAAK,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;AAEtD;;;;;;;;;;;;;;;GAeG;AACH,iBAAS,IAAI,CAAC,EACZ,SAAS,EACT,MAAM,EACN,IAAgB,EAChB,OAAmB,EACnB,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IACnC,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB,0EAsBA;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWvE;AAED,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,qBAazD;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQ5E;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQvE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAIxE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWvE;AAED,OAAO,EACL,IAAI,EACJ,UAAU,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,EACf,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,CAAC"}
1
+ {"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../src/components/card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAItD,KAAK,WAAW,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;AAC/D,KAAK,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,MAAM,CAAC;AAEtD;;;;;;;;;GASG;AACH,iBAAS,IAAI,CAAC,EACZ,SAAS,EACT,MAAM,EACN,IAAgB,EAChB,OAAmB,EACnB,OAAmB,EACnB,GAAG,KAAK,EACT,EAAE,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IACnC,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB,0EAwBA;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWvE;AAED,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,WAAmB,EACnB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,qBAazD;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQ5E;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAQvE;AAED,iBAAS,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAIxE;AAED,iBAAS,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAWvE;AAED,OAAO,EACL,IAAI,EACJ,UAAU,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,eAAe,EACf,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,WAAW,GACjB,CAAC"}
@@ -3,26 +3,21 @@ import { mergeProps } from "@base-ui/react/merge-props";
3
3
  import { useRender } from "@base-ui/react/use-render";
4
4
  import { cn } from "../lib/utils.js";
5
5
  /**
6
- * A resting surface that holds one thing: a header, content and a recessed footer.
6
+ * The surface of every card; on its own only a container inside a composition.
7
7
  *
8
8
  * @family Data
9
- * @when A bounded piece of a page that stands on its own: a settings section, a KPI, a chart, a
10
- * table. Usually reached through the composition that owns that job.
11
- * @instead A page's own header is never in a card. A row of a list is `Item`. A plane of brand
12
- * colour is `BrandField`.
13
- * @behaviour The resting material: 6 px corners and the rest shadow, no border of its own.
14
- * `CardHeader` lays out title, description and one `CardAction`; `CardFooter` is the recessed strip
15
- * behind one seam. `size="sm"` for a compact card in a side column.
16
- * @words The title is a noun phrase naming what the card holds; the description one sentence, only
17
- * when it adds something.
18
- * @access A plain container; give it `render={<section />}` with a heading when it is a region of
19
- * the page.
9
+ * @when "For in-product cards and dashboard tiles, use `Card`; Book is too decorative for repeated UI rows." (https://vercel.com/geist/book) Ours: only inside a composition that owns the job: the object card of an `ObjectPage`, the setting card of a `SettingsSection`, a KPI, a chart, a table. A new kind of card is a new composition, never a `Card` assembled at a call site.
10
+ * @instead "Groups related form controls inside a bordered card with optional footer actions." (https://vercel.com/geist/fieldset) Ours: that card, a title and description, one control and a footer with help at the start and one action at the end, is `SettingsSection`. An object's card (a header bar with its name and commands, a body of facts, rows that open, a footer hint with one link elsewhere) is `ObjectPage`. The page's title row is never in a card. A row of a list is `Item`. A plane of brand colour is `BrandField`.
11
+ * @behaviour "One Note per concept." (https://vercel.com/geist/note) "Stacking three Notes on a card means the page architecture, not the Note copy, is wrong." (https://vercel.com/geist/note) "Use the Error component as a block surface when a section or page-level resource failed to load: a panel, a dashboard card, a route boundary." (https://vercel.com/geist/error) Ours: the corner and shadow come with `surface`: a raised card takes the larger corner. Never set a corner at the call site. `CardHeader` lays out title, description and one `CardAction`, which stays at the title's right at every width when it is one control (a button, a badge, the three dots) and moves under the description in a header narrower than 28rem when it holds several; `CardFooter` is the recessed strip behind one seam: on the left one short muted line (a hint, a constraint, the plan a feature needs), on the right at most one button or link. It is 56 px high whether or not it holds a button, and as high as its lines in a `size="sm"` card, the compact card of a side column or a figure. The two kinds differ in what their header and footer hold: an object card's header holds the object's commands and its footer only a link, so it never saves; a setting card's header holds a title, a description and at most a switch that applies on change, and its footer holds the Save. A card is neutral; colour enters only through a status inside it or a section's `tone`.
12
+ * @words The title is a noun phrase naming what the card holds; the description one sentence directly under it, only when it adds something.
13
+ * @access A plain container; give it `render={<section />}` with a heading when it is a region of the page.
20
14
  */
21
15
  function Card({ className, render, size = "default", surface = "resting", variant = "default", ...props }) {
22
16
  const structure = cn("group/card flex flex-col gap-(--card-spacing) overflow-hidden bg-card py-(--card-spacing) text-sm text-card-foreground [--card-spacing:var(--spacing-nadicode-card-padding)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:var(--spacing-nadicode-md)] data-[size=sm]:has-data-[slot=card-footer]:pb-0", variant === "interactive" && "cursor-pointer", variant === "link" && "nc-transition-paint");
17
+ const corner = surface === "raised" ? "rounded-lg" : "rounded-sm";
23
18
  const surfaceClassName = surface === "outlined"
24
- ? cn(structure, "rounded-sm border border-border", className)
25
- : cn(structure, "rounded-sm border-0 *:[img:first-child]:rounded-t-sm *:[img:last-child]:rounded-b-sm", surface === "resting" && "nc-elevation-resting", surface === "raised" && "nc-elevation-raised", className);
19
+ ? cn(structure, corner, "border border-border", className)
20
+ : cn(structure, corner, "border-0 *:[img:first-child]:rounded-t-[inherit] *:[img:last-child]:rounded-b-[inherit]", surface === "resting" && "nc-elevation-resting", surface === "raised" && "nc-elevation-raised", className);
26
21
  return useRender({
27
22
  defaultTagName: "div",
28
23
  props: mergeProps({ className: surfaceClassName }, props),
@@ -31,7 +26,7 @@ function Card({ className, render, size = "default", surface = "resting", varian
31
26
  });
32
27
  }
33
28
  function CardHeader({ className, ...props }) {
34
- return (_jsx("div", { "data-slot": "card-header", className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-sm px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[minmax(0,1fr)_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] *:data-[slot=card-description]:col-start-1 *:data-[slot=card-title]:col-start-1 [.border-b]:pb-(--card-spacing)", className), ...props }));
29
+ return (_jsx("div", { "data-slot": "card-header", className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-x-1 gap-y-2 rounded-t-[inherit] px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[minmax(0,1fr)_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] *:data-[slot=card-description]:col-start-1 *:data-[slot=card-title]:col-start-1 [.border-b]:pb-(--card-spacing)", className), ...props }));
35
30
  }
36
31
  function CardTitle({ className, focusTarget = false, ...props }) {
37
32
  return (_jsx("div", { "data-slot": "card-title", "data-focus-target": focusTarget || undefined, className: cn("text-heading-sm group-data-[size=sm]/card:text-heading-xs", focusTarget && "rounded-sm", className), ...props }));
@@ -46,6 +41,6 @@ function CardContent({ className, ...props }) {
46
41
  return (_jsx("div", { "data-slot": "card-content", className: cn("px-(--card-spacing)", className), ...props }));
47
42
  }
48
43
  function CardFooter({ className, ...props }) {
49
- return (_jsx("div", { "data-slot": "card-footer", className: cn("flex flex-wrap items-center gap-3 border-t border-border bg-recessed px-(--card-spacing) py-3", className), ...props }));
44
+ return (_jsx("div", { "data-slot": "card-footer", className: cn("mt-auto flex min-h-14 flex-wrap items-center gap-3 border-t border-border bg-recessed px-(--card-spacing) py-3 text-sm text-muted-foreground group-data-[size=sm]/card:min-h-0", className), ...props }));
50
45
  }
51
46
  export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent, };
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
2
  import useEmblaCarousel, { type UseEmblaCarouselType } from "embla-carousel-react";
3
- import { Button } from "./button.js";
3
+ import { type IconButtonPartProps } from "./button.js";
4
4
  type CarouselApi = UseEmblaCarouselType[1];
5
5
  type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
6
6
  type CarouselOptions = UseCarouselParameters[0];
@@ -35,7 +35,7 @@ declare function useCarousel(): CarouselContextProps;
35
35
  declare function Carousel({ orientation, opts, setApi, plugins, className, children, ...props }: React.ComponentProps<"div"> & CarouselProps): React.JSX.Element;
36
36
  declare function CarouselContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
37
37
  declare function CarouselItem({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
38
- declare function CarouselPrevious({ className, variant, size, ...props }: React.ComponentProps<typeof Button>): React.JSX.Element;
39
- declare function CarouselNext({ className, variant, size, ...props }: React.ComponentProps<typeof Button>): React.JSX.Element;
38
+ declare function CarouselPrevious({ className, variant, size, "aria-label": ariaLabel, ...props }: IconButtonPartProps): React.JSX.Element;
39
+ declare function CarouselNext({ className, variant, size, "aria-label": ariaLabel, ...props }: IconButtonPartProps): React.JSX.Element;
40
40
  export { type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, useCarousel, };
41
41
  //# sourceMappingURL=carousel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../../src/components/carousel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,gBAAgB,EAAE,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGnF,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,KAAK,WAAW,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC3C,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,KAAK,eAAe,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAChD,KAAK,cAAc,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAE/C,KAAK,aAAa,GAAG;IACnB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,WAAW,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,GAAG,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,aAAa,CAAC;AAIlB,iBAAS,WAAW,yBAQnB;AAED;;;;;;;;;;;GAWG;AACH,iBAAS,QAAQ,CAAC,EAChB,WAA0B,EAC1B,IAAI,EACJ,MAAM,EACN,OAAO,EACP,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,aAAa,qBAgF7C;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW5E;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAgBzE;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,qBAwBrC;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,qBAwBrC;AAED,OAAO,EACL,KAAK,WAAW,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,WAAW,GACZ,CAAC"}
1
+ {"version":3,"file":"carousel.d.ts","sourceRoot":"","sources":["../../src/components/carousel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,gBAAgB,EAAE,EAAE,KAAK,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGnF,OAAO,EAAU,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAGvE,KAAK,WAAW,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC3C,KAAK,qBAAqB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACjE,KAAK,eAAe,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAChD,KAAK,cAAc,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAE/C,KAAK,aAAa,GAAG;IACnB,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,KAAK,oBAAoB,GAAG;IAC1B,WAAW,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,GAAG,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5C,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,aAAa,CAAC;AAIlB,iBAAS,WAAW,yBAQnB;AAED;;;;;;;;;;;GAWG;AACH,iBAAS,QAAQ,CAAC,EAChB,WAA0B,EAC1B,IAAI,EACJ,MAAM,EACN,OAAO,EACP,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,aAAa,qBAgF7C;AAED,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAW5E;AAED,iBAAS,YAAY,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,qBAgBzE;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,YAAY,EAAE,SAA4B,EAC1C,GAAG,KAAK,EACT,EAAE,mBAAmB,qBAuBrB;AAED,iBAAS,YAAY,CAAC,EACpB,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,YAAY,EAAE,SAAwB,EACtC,GAAG,KAAK,EACT,EAAE,mBAAmB,qBAuBrB;AAED,OAAO,EACL,KAAK,WAAW,EAChB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,WAAW,GACZ,CAAC"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import useEmblaCarousel from "embla-carousel-react";
5
5
  import { cn } from "../lib/utils.js";
@@ -89,16 +89,16 @@ function CarouselItem({ className, ...props }) {
89
89
  const { orientation } = useCarousel();
90
90
  return (_jsx("div", { role: "group", "aria-roledescription": "slide", "data-slot": "carousel-item", className: cn("min-w-0 shrink-0 grow-0 basis-full", orientation === "horizontal" ? "pl-4" : "pt-4", className), ...props }));
91
91
  }
92
- function CarouselPrevious({ className, variant = "outline", size = "icon-sm", ...props }) {
92
+ function CarouselPrevious({ className, variant = "outline", size = "icon-sm", "aria-label": ariaLabel = "Previous slide", ...props }) {
93
93
  const { orientation, scrollPrev, canScrollPrev } = useCarousel();
94
- return (_jsxs(Button, { "data-slot": "carousel-previous", variant: variant, size: size, className: cn("absolute touch-manipulation", orientation === "horizontal"
94
+ return (_jsx(Button, { "data-slot": "carousel-previous", "aria-label": ariaLabel, variant: variant, size: size, className: cn("absolute touch-manipulation", orientation === "horizontal"
95
95
  ? "inset-y-0 -left-12 my-auto"
96
- : "-top-12 left-1/2 -translate-x-1/2 rotate-90", className), disabled: !canScrollPrev, onClick: scrollPrev, ...props, children: [_jsx(ChevronLeftIcon, {}), _jsx("span", { className: "sr-only", children: "Previous slide" })] }));
96
+ : "-top-12 left-1/2 -translate-x-1/2 rotate-90", className), disabled: !canScrollPrev, onClick: scrollPrev, ...props, children: _jsx(ChevronLeftIcon, {}) }));
97
97
  }
98
- function CarouselNext({ className, variant = "outline", size = "icon-sm", ...props }) {
98
+ function CarouselNext({ className, variant = "outline", size = "icon-sm", "aria-label": ariaLabel = "Next slide", ...props }) {
99
99
  const { orientation, scrollNext, canScrollNext } = useCarousel();
100
- return (_jsxs(Button, { "data-slot": "carousel-next", variant: variant, size: size, className: cn("absolute touch-manipulation", orientation === "horizontal"
100
+ return (_jsx(Button, { "data-slot": "carousel-next", "aria-label": ariaLabel, variant: variant, size: size, className: cn("absolute touch-manipulation", orientation === "horizontal"
101
101
  ? "inset-y-0 -right-12 my-auto"
102
- : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90", className), disabled: !canScrollNext, onClick: scrollNext, ...props, children: [_jsx(ChevronRightIcon, {}), _jsx("span", { className: "sr-only", children: "Next slide" })] }));
102
+ : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90", className), disabled: !canScrollNext, onClick: scrollNext, ...props, children: _jsx(ChevronRightIcon, {}) }));
103
103
  }
104
104
  export { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext, useCarousel, };
@@ -2,7 +2,7 @@ import type { CatalogSection } from "./catalog-entry.js";
2
2
  import { type CollectionSearchProps } from "./collection-search.js";
3
3
  import { type EmptyStateKind } from "./empty-state.js";
4
4
  import { type FormSurfaceProps } from "./form-drawer.js";
5
- export type CatalogDrawerProps = Omit<FormSurfaceProps, "children"> & {
5
+ export type CatalogDrawerProps = Omit<FormSurfaceProps, "children" | "unsaved"> & {
6
6
  search: CollectionSearchProps;
7
7
  /** Already searched; undefined while the catalogue loads. */
8
8
  sections: readonly CatalogSection[] | undefined;
@@ -16,14 +16,14 @@ export type CatalogDrawerProps = Omit<FormSurfaceProps, "children"> & {
16
16
  done: string;
17
17
  };
18
18
  /**
19
- * A catalogue to choose from in the right-side drawer, each entry added from its own row.
19
+ * A catalogue to choose from in the right-side sheet, each entry added from its own row.
20
20
  *
21
21
  * @family Compositions
22
- * @when A person picks one or more things from a list too long for a dialog, the page still behind it: add a skill, add an app to a new Agent.
23
- * @instead The shelf of everything the company holds, on its own page, is a `LibraryShelf`; a setup in steps is a `FormDrawer` with `job="steps"`; a new record from a few fields is a `FormDialog`.
24
- * @behaviour The header holds the title, the description and Close; the body holds the search, then the entries in one column under their section titles. It draws one state at a time: the failure with its retry, three still entries while the catalogue loads, no match with a way to clear the search, nothing at all, or the entries. An entry already held shows a muted check and its word in place of Add. The footer's one button closes the drawer.
25
- * @words The title names the job: "Add a skill". The search names what it finds: "Search the hub". Each entry's button is "Add"; the held word is "Added"; the footer's is "Done".
26
- * @access A modal dialog named by its title; focus starts in the search, Escape and Close close it, and focus returns to the opener. The loading entries are one status named by `loadingLabel`.
22
+ * @when Ours: a person picks one or more things from a list too long for a dialog, the page still behind it: add a skill, add an app to a new Agent.
23
+ * @instead "Don’t use Sheet to confirm destructive actions. The default `modal=false` keeps the page interactive, which weakens severity for a delete or revoke." (https://vercel.com/geist/sheet) Ours: the shelf of everything the company holds, on its own page, is a `LibraryShelf`; a setup in steps is a `FormDrawer` with `job="steps"`; a new record from a few fields is a `FormDialog`.
24
+ * @behaviour "Outside-click does not auto-close, so always render an explicit close affordance and honor Escape." (https://vercel.com/geist/sheet) Ours: a modal sheet from the right, as `FormDrawer`. The header holds the title, the description and Close; the body holds the search, then the entries in one column under their section titles. It draws one state at a time: the failure with its retry, three still entries while the catalogue loads, no match with a way to clear the search, nothing at all, or the entries. An entry already held shows a muted check and its word in place of Add. The footer's one button closes the drawer.
25
+ * @words "Title is Title Case and names the entity (`Deployment Details`, `Member Profile`), not the page action." (https://vercel.com/geist/sheet) "Cancel literal stays `Cancel`. Acknowledgment-only Modals (after a key reveal, after a one-time-show) use `Done`, never `OK` or `Close`." (https://vercel.com/geist/modal) Ours: the title is sentence case and names the job: "Add a skill". The search names what it finds: "Search the hub". Each entry's button is "Add"; the held word is "Added"; the footer's is "Done".
26
+ * @access "Trap focus inside the sheet while it’s open and return focus to the trigger row on close so keyboard users keep their place in the list." (https://vercel.com/geist/sheet) "Provide a visible close button labeled `Close` (or an icon button with `aria-label="Close"`) since clicking outside doesn’t dismiss." (https://vercel.com/geist/sheet) Ours: a modal dialog named by its title; focus starts in the search. The loading entries are one status named by `loadingLabel`.
27
27
  */
28
28
  export declare function CatalogDrawer({ search, sections, loadingLabel, failed, empty, noMatch, done, ...surface }: CatalogDrawerProps): import("react").JSX.Element;
29
29
  //# sourceMappingURL=catalog-drawer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-drawer.d.ts","sourceRoot":"","sources":["../../src/components/catalog-drawer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC9F,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAIlC,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC,GAAG;IACpE,MAAM,EAAE,qBAAqB,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAC;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IAClC,0CAA0C;IAC1C,KAAK,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IACpC,qGAAqG;IACrG,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC;IACpD,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,KAAK,EACL,OAAO,EACP,IAAI,EACJ,GAAG,OAAO,EACX,EAAE,kBAAkB,+BAoBpB"}
1
+ {"version":3,"file":"catalog-drawer.d.ts","sourceRoot":"","sources":["../../src/components/catalog-drawer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAoB,KAAK,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC9F,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC3E,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,0BAA0B,CAAC;AAIlC,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,gBAAgB,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAChF,MAAM,EAAE,qBAAqB,CAAC;IAC9B,6DAA6D;IAC7D,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,CAAC;IAChD,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;IAClC,0CAA0C;IAC1C,KAAK,EAAE,cAAc,CAAC,YAAY,CAAC,CAAC;IACpC,qGAAqG;IACrG,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,CAAC;IACpD,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,KAAK,EACL,OAAO,EACP,IAAI,EACJ,GAAG,OAAO,EACX,EAAE,kBAAkB,+BAoBpB"}
@@ -7,14 +7,14 @@ import { FormDrawer, FormDrawerBody, FormDrawerFooter, } from "./form-drawer.js"
7
7
  import { SheetClose } from "./sheet.js";
8
8
  import { CatalogList, CatalogSkeleton, catalogIsEmpty } from "../internal/catalog-list.js";
9
9
  /**
10
- * A catalogue to choose from in the right-side drawer, each entry added from its own row.
10
+ * A catalogue to choose from in the right-side sheet, each entry added from its own row.
11
11
  *
12
12
  * @family Compositions
13
- * @when A person picks one or more things from a list too long for a dialog, the page still behind it: add a skill, add an app to a new Agent.
14
- * @instead The shelf of everything the company holds, on its own page, is a `LibraryShelf`; a setup in steps is a `FormDrawer` with `job="steps"`; a new record from a few fields is a `FormDialog`.
15
- * @behaviour The header holds the title, the description and Close; the body holds the search, then the entries in one column under their section titles. It draws one state at a time: the failure with its retry, three still entries while the catalogue loads, no match with a way to clear the search, nothing at all, or the entries. An entry already held shows a muted check and its word in place of Add. The footer's one button closes the drawer.
16
- * @words The title names the job: "Add a skill". The search names what it finds: "Search the hub". Each entry's button is "Add"; the held word is "Added"; the footer's is "Done".
17
- * @access A modal dialog named by its title; focus starts in the search, Escape and Close close it, and focus returns to the opener. The loading entries are one status named by `loadingLabel`.
13
+ * @when Ours: a person picks one or more things from a list too long for a dialog, the page still behind it: add a skill, add an app to a new Agent.
14
+ * @instead "Don’t use Sheet to confirm destructive actions. The default `modal=false` keeps the page interactive, which weakens severity for a delete or revoke." (https://vercel.com/geist/sheet) Ours: the shelf of everything the company holds, on its own page, is a `LibraryShelf`; a setup in steps is a `FormDrawer` with `job="steps"`; a new record from a few fields is a `FormDialog`.
15
+ * @behaviour "Outside-click does not auto-close, so always render an explicit close affordance and honor Escape." (https://vercel.com/geist/sheet) Ours: a modal sheet from the right, as `FormDrawer`. The header holds the title, the description and Close; the body holds the search, then the entries in one column under their section titles. It draws one state at a time: the failure with its retry, three still entries while the catalogue loads, no match with a way to clear the search, nothing at all, or the entries. An entry already held shows a muted check and its word in place of Add. The footer's one button closes the drawer.
16
+ * @words "Title is Title Case and names the entity (`Deployment Details`, `Member Profile`), not the page action." (https://vercel.com/geist/sheet) "Cancel literal stays `Cancel`. Acknowledgment-only Modals (after a key reveal, after a one-time-show) use `Done`, never `OK` or `Close`." (https://vercel.com/geist/modal) Ours: the title is sentence case and names the job: "Add a skill". The search names what it finds: "Search the hub". Each entry's button is "Add"; the held word is "Added"; the footer's is "Done".
17
+ * @access "Trap focus inside the sheet while it’s open and return focus to the trigger row on close so keyboard users keep their place in the list." (https://vercel.com/geist/sheet) "Provide a visible close button labeled `Close` (or an icon button with `aria-label="Close"`) since clicking outside doesn’t dismiss." (https://vercel.com/geist/sheet) Ours: a modal dialog named by its title; focus starts in the search. The loading entries are one status named by `loadingLabel`.
18
18
  */
19
19
  export function CatalogDrawer({ search, sections, loadingLabel, failed, empty, noMatch, done, ...surface }) {
20
20
  return (_jsxs(FormDrawer, { ...surface, job: "catalog", children: [_jsx("div", { className: "px-nadicode-lg", "data-slot": "catalog-drawer-search", children: _jsx(CollectionSearch, { ...search }) }), _jsx(FormDrawerBody, { className: "pb-nadicode-lg", children: _jsx(CatalogBody, { empty: empty, failed: failed, loadingLabel: loadingLabel, noMatch: search.value ? noMatch : undefined, sections: sections }) }), _jsx(FormDrawerFooter, { children: _jsx(SheetClose, { render: _jsx(Button, { type: "button" }), children: done }) })] }));
@@ -9,6 +9,6 @@ import { type ChartCardProps } from "./chart-card.js";
9
9
  * @words Series named for what the person buys: "Included usage", "Extra usage". Axis scale in M; the tooltip prints the exact token count.
10
10
  * @access Named by its title. A delta that is neither good nor bad, like volume, takes the neutral tone.
11
11
  */
12
- declare function ChartAreaStacked({ title, period, controls, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter, axisFormatter, otherLabel, emptyState, size, className, }: ChartCardProps): import("react").JSX.Element;
12
+ declare function ChartAreaStacked({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter, axisFormatter, otherLabel, emptyState, size, className, }: ChartCardProps): import("react").JSX.Element;
13
13
  export { ChartAreaStacked };
14
14
  //# sourceMappingURL=chart-area-stacked.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-area-stacked.d.ts","sourceRoot":"","sources":["../../src/components/chart-area-stacked.tsx"],"names":[],"mappings":"AAcA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;;GASG;AACH,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,UAAU,EACV,IAAgB,EAChB,SAAS,GACV,EAAE,cAAc,+BA0EhB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"chart-area-stacked.d.ts","sourceRoot":"","sources":["../../src/components/chart-area-stacked.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;;GASG;AACH,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,UAAU,EACV,IAAgB,EAChB,SAAS,GACV,EAAE,cAAc,+BAiFhB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -4,7 +4,7 @@
4
4
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";
6
6
  import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, } from "./chart.js";
7
- import { CHART_Y_AXIS_TICK_COUNT, niceAxisTicks, stackedAxisMax } from "./chart-axis.js";
7
+ import { CHART_X_AXIS_TICKS, CHART_Y_AXIS_TICK_COUNT, niceAxisTicks, stackedAxisMax, } from "./chart-axis.js";
8
8
  import { CHART_LEGEND_CLASS, ChartCard, chartPlotClassName, chartSeriesConfig, defaultValueFormatter, foldOtherSeries, } from "./chart-card.js";
9
9
  import { entityColor } from "./chart-entity-colors.js";
10
10
  /**
@@ -17,14 +17,14 @@ import { entityColor } from "./chart-entity-colors.js";
17
17
  * @words Series named for what the person buys: "Included usage", "Extra usage". Axis scale in M; the tooltip prints the exact token count.
18
18
  * @access Named by its title. A delta that is neither good nor bad, like volume, takes the neutral tone.
19
19
  */
20
- function ChartAreaStacked({ title, period, controls, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter = defaultValueFormatter, axisFormatter, otherLabel, emptyState, size = "default", className, }) {
20
+ function ChartAreaStacked({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter = defaultValueFormatter, axisFormatter, otherLabel, emptyState, size = "default", className, }) {
21
21
  const folded = foldOtherSeries(series, data, entityColorMap, otherLabel);
22
22
  const chartConfig = chartSeriesConfig(folded.series, entityColorMap);
23
23
  const domainMax = stackedAxisMax(folded.data, folded.series.map((entry) => entry.id));
24
- return (_jsx(ChartCard, { title: title, period: period, controls: controls, summary: summary, aside: aside, ...(footer ? { footer } : {}), ...(headingLevel ? { headingLevel } : {}), className: className, children: (titleId) => emptyState && data.length === 0 ? (emptyState) : (_jsx(ChartContainer, { config: chartConfig, className: chartPlotClassName(size), children: _jsxs(AreaChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: folded.data, margin: {
24
+ return (_jsx(ChartCard, { title: title, period: period, controls: controls, ...(link ? { link } : {}), summary: summary, aside: aside, ...(footer ? { footer } : {}), ...(headingLevel ? { headingLevel } : {}), className: className, children: (titleId) => emptyState && data.length === 0 ? (emptyState) : (_jsx(ChartContainer, { config: chartConfig, className: chartPlotClassName(size), children: _jsxs(AreaChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: folded.data, margin: {
25
25
  left: 12,
26
26
  right: 12,
27
- }, children: [_jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: xKey, tickLine: false, axisLine: false, tickMargin: 8 }), _jsx(YAxis, { width: "auto", tickLine: false, axisLine: false, tickMargin: 8, tickCount: CHART_Y_AXIS_TICK_COUNT, ...(domainMax === undefined
27
+ }, children: [_jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: xKey, tickLine: false, axisLine: false, tickMargin: 8, ...CHART_X_AXIS_TICKS }), _jsx(YAxis, { width: "auto", tickLine: false, axisLine: false, tickMargin: 8, tickCount: CHART_Y_AXIS_TICK_COUNT, ...(domainMax === undefined
28
28
  ? {}
29
29
  : {
30
30
  domain: [0, domainMax],
@@ -8,6 +8,19 @@
8
8
  * y axis of five ticks whose maximum is rounded up to a step a reader counts
9
9
  * in: 1, 2, 2.5, 5 or 10 per order of magnitude.
10
10
  */
11
+ /**
12
+ * The category axis labels every Nth period from the first, the same N across
13
+ * the plot: every second day where the labels fit, as OpenRouter's daily charts
14
+ * do, and every third or fourth in a half-width card. Recharts' default fits
15
+ * labels by their own widths, so a short "Oct 1" squeezed in beside "Oct 2"
16
+ * while "Sep 30" was dropped. Anchoring the step on the latest period instead
17
+ * left a half-width chart with that one label, cut by the card's edge, because
18
+ * Recharts always draws the anchor and the latest label overflows the plot.
19
+ */
20
+ declare const CHART_X_AXIS_TICKS: {
21
+ readonly interval: "equidistantPreserveStart";
22
+ readonly minTickGap: 12;
23
+ };
11
24
  /** Ticks the y axis draws, ends included. */
12
25
  declare const CHART_Y_AXIS_TICK_COUNT = 5;
13
26
  declare function niceStep(rawStep: number): number;
@@ -34,5 +47,5 @@ declare function stackedAxisMax(data: readonly AxisDatum[], keys: readonly strin
34
47
  * a zero-based one.
35
48
  */
36
49
  declare function seriesAxisMax(data: readonly AxisDatum[], keys: readonly string[]): number | undefined;
37
- export { CHART_Y_AXIS_TICK_COUNT, niceAxisMax, niceAxisTicks, niceStep, seriesAxisMax, stackedAxisMax, };
50
+ export { CHART_X_AXIS_TICKS, CHART_Y_AXIS_TICK_COUNT, niceAxisMax, niceAxisTicks, niceStep, seriesAxisMax, stackedAxisMax, };
38
51
  //# sourceMappingURL=chart-axis.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-axis.d.ts","sourceRoot":"","sources":["../../src/components/chart-axis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,6CAA6C;AAC7C,QAAA,MAAM,uBAAuB,IAAI,CAAC;AAKlC,iBAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMzC;AAED;;;;GAIG;AACH,iBAAS,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIpD;AAED;;;;;GAKG;AACH,iBAAS,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,SAAS,CAOpE;AAED,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAEjD,0EAA0E;AAC1E,iBAAS,cAAc,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAY/F;AAED;;;;;GAKG;AACH,iBAAS,aAAa,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAY9F;AAED,OAAO,EACL,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,aAAa,EACb,cAAc,GACf,CAAC"}
1
+ {"version":3,"file":"chart-axis.d.ts","sourceRoot":"","sources":["../../src/components/chart-axis.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;GAQG;AACH,QAAA,MAAM,kBAAkB;;;CAAoE,CAAC;AAE7F,6CAA6C;AAC7C,QAAA,MAAM,uBAAuB,IAAI,CAAC;AAKlC,iBAAS,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMzC;AAED;;;;GAIG;AACH,iBAAS,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIpD;AAED;;;;;GAKG;AACH,iBAAS,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,GAAG,SAAS,CAOpE;AAED,KAAK,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAEjD,0EAA0E;AAC1E,iBAAS,cAAc,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAY/F;AAED;;;;;GAKG;AACH,iBAAS,aAAa,CAAC,IAAI,EAAE,SAAS,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAY9F;AAED,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,QAAQ,EACR,aAAa,EACb,cAAc,GACf,CAAC"}
@@ -8,6 +8,16 @@
8
8
  * y axis of five ticks whose maximum is rounded up to a step a reader counts
9
9
  * in: 1, 2, 2.5, 5 or 10 per order of magnitude.
10
10
  */
11
+ /**
12
+ * The category axis labels every Nth period from the first, the same N across
13
+ * the plot: every second day where the labels fit, as OpenRouter's daily charts
14
+ * do, and every third or fourth in a half-width card. Recharts' default fits
15
+ * labels by their own widths, so a short "Oct 1" squeezed in beside "Oct 2"
16
+ * while "Sep 30" was dropped. Anchoring the step on the latest period instead
17
+ * left a half-width chart with that one label, cut by the card's edge, because
18
+ * Recharts always draws the anchor and the latest label overflows the plot.
19
+ */
20
+ const CHART_X_AXIS_TICKS = { interval: "equidistantPreserveStart", minTickGap: 12 };
11
21
  /** Ticks the y axis draws, ends included. */
12
22
  const CHART_Y_AXIS_TICK_COUNT = 5;
13
23
  /** The steps a reader counts in, per order of magnitude. */
@@ -82,4 +92,4 @@ function seriesAxisMax(data, keys) {
82
92
  }
83
93
  return niceAxisMax(max);
84
94
  }
85
- export { CHART_Y_AXIS_TICK_COUNT, niceAxisMax, niceAxisTicks, niceStep, seriesAxisMax, stackedAxisMax, };
95
+ export { CHART_X_AXIS_TICKS, CHART_Y_AXIS_TICK_COUNT, niceAxisMax, niceAxisTicks, niceStep, seriesAxisMax, stackedAxisMax, };
@@ -11,9 +11,9 @@ declare function signedAxis(data: readonly Record<string, number | string>[], va
11
11
  * @instead Never encode a loss as a share. An unsigned ranking is the compact `Progress` ranking or a `DataTable`.
12
12
  * @behaviour Horizontal bars from a 1.5 px zero line: favourable values to the right in success with right corners rounded, unfavourable to the left in destructive with left corners rounded.
13
13
  * @words The money unit in the period or the axis. Losses stay negative, written with a true minus: −€360.
14
- * @access Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: every category keeps its label on one line, a long one cut with an ellipsis and whole in the tooltip.
14
+ * @access Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: the axis is as wide as the longest label up to 128 px, a longer one wraps to a second line and only past that is cut with an ellipsis, whole in the tooltip.
15
15
  */
16
- declare function ChartBarHorizontal({ title, period, controls, summary, aside, footer, headingLevel, data, xKey, valueKey, displayKey, categoryDisplayKey, positiveLabel, negativeLabel, valueFormatter, axisFormatter, emptyState, size, className, }: Omit<ChartCardProps, "series" | "entityColorMap" | "otherLabel"> & {
16
+ declare function ChartBarHorizontal({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, valueKey, displayKey, categoryDisplayKey, positiveLabel, negativeLabel, valueFormatter, axisFormatter, emptyState, size, className, }: Omit<ChartCardProps, "series" | "entityColorMap" | "otherLabel"> & {
17
17
  valueKey: string;
18
18
  displayKey?: string;
19
19
  categoryDisplayKey?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"chart-bar-horizontal.d.ts","sourceRoot":"","sources":["../../src/components/chart-bar-horizontal.tsx"],"names":[],"mappings":"AAaA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAsBjC,iBAAS,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM;;;EAqCrF;AAED;;;;;;;;;GASG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,QAAQ,EACR,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,IAAgB,EAChB,SAAS,GACV,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,gBAAgB,GAAG,YAAY,CAAC,GAAG;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,+BA8GA;AAED,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"chart-bar-horizontal.d.ts","sourceRoot":"","sources":["../../src/components/chart-bar-horizontal.tsx"],"names":[],"mappings":"AAaA,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAoCjC,iBAAS,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM;;;EAqCrF;AAED;;;;;;;;;GASG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,IAAgB,EAChB,SAAS,GACV,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,gBAAgB,GAAG,YAAY,CAAC,GAAG;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,+BA+GA;AAED,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,CAAC"}
@@ -11,10 +11,19 @@ const POSITIVE_BAR_COLOR = "var(--success)";
11
11
  const NEGATIVE_BAR_COLOR = "var(--destructive)";
12
12
  /**
13
13
  * Recharts keeps only SVG attributes from a `tick` object, so `maxLines` reaches
14
- * its `Text` only through a tick it renders: one line, cut with an ellipsis.
14
+ * its `Text` only through a tick it renders: up to two lines, then an ellipsis.
15
15
  */
16
16
  function CategoryTick({ payload, ...props }) {
17
- return (_jsx(Text, { ...props, maxLines: 1, children: payload.value }));
17
+ return (_jsx(Text, { ...props, maxLines: 2, children: payload.value }));
18
+ }
19
+ /** About one 12 px character, and the bounds that keep a name whole on two lines without starving the bars. */
20
+ const CATEGORY_CHAR_WIDTH = 6.6;
21
+ const CATEGORY_AXIS_MIN = 64;
22
+ const CATEGORY_AXIS_MAX = 128;
23
+ /** The category axis as wide as its longest name up to the bound; a longer name wraps to a second line. */
24
+ function categoryAxisWidth(data, xKey) {
25
+ const longest = data.reduce((most, datum) => Math.max(most, String(datum[xKey] ?? "").length), 0);
26
+ return Math.min(CATEGORY_AXIS_MAX, Math.max(CATEGORY_AXIS_MIN, Math.ceil(longest * CATEGORY_CHAR_WIDTH) + 16));
18
27
  }
19
28
  function signedAxis(data, valueKey) {
20
29
  const values = data.flatMap((datum) => {
@@ -53,9 +62,9 @@ function signedAxis(data, valueKey) {
53
62
  * @instead Never encode a loss as a share. An unsigned ranking is the compact `Progress` ranking or a `DataTable`.
54
63
  * @behaviour Horizontal bars from a 1.5 px zero line: favourable values to the right in success with right corners rounded, unfavourable to the left in destructive with left corners rounded.
55
64
  * @words The money unit in the period or the axis. Losses stay negative, written with a true minus: −€360.
56
- * @access Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: every category keeps its label on one line, a long one cut with an ellipsis and whole in the tooltip.
65
+ * @access Each bar's sign is in its position and its tooltip, never only its colour. Category labels are text, readable without hue: the axis is as wide as the longest label up to 128 px, a longer one wraps to a second line and only past that is cut with an ellipsis, whole in the tooltip.
57
66
  */
58
- function ChartBarHorizontal({ title, period, controls, summary, aside, footer, headingLevel, data, xKey, valueKey, displayKey, categoryDisplayKey, positiveLabel, negativeLabel, valueFormatter = defaultValueFormatter, axisFormatter, emptyState, size = "default", className, }) {
67
+ function ChartBarHorizontal({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, valueKey, displayKey, categoryDisplayKey, positiveLabel, negativeLabel, valueFormatter = defaultValueFormatter, axisFormatter, emptyState, size = "default", className, }) {
59
68
  const axis = signedAxis(data, valueKey);
60
69
  const signedData = data.map((datum) => {
61
70
  const value = datum[valueKey];
@@ -71,7 +80,7 @@ function ChartBarHorizontal({ title, period, controls, summary, aside, footer, h
71
80
  [POSITIVE_KEY]: { label: positiveLabel, color: POSITIVE_BAR_COLOR },
72
81
  [NEGATIVE_KEY]: { label: negativeLabel, color: NEGATIVE_BAR_COLOR },
73
82
  };
74
- return (_jsx(ChartCard, { title: title, period: period, controls: controls, summary: summary, aside: aside, ...(footer ? { footer } : {}), ...(headingLevel ? { headingLevel } : {}), className: className, children: (titleId) => emptyState && data.length === 0 ? (emptyState) : (_jsx(ChartContainer, { config: chartConfig, className: chartPlotClassName(size), children: _jsxs(BarChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: signedData, layout: "vertical", margin: { left: 8, right: 16 }, children: [_jsx(CartesianGrid, { horizontal: false, strokeDasharray: "3 3" }), _jsx(XAxis, { type: "number", domain: axis.domain, ticks: axis.ticks, tickLine: false, axisLine: false, tickMargin: 8, tickFormatter: (value) => (axisFormatter ?? valueFormatter)(Number(value)) }), _jsx(YAxis, { type: "category", dataKey: xKey, width: 112, interval: 0, tick: CategoryTick, tickLine: false, axisLine: false, tickMargin: 8 }), _jsx(ReferenceLine, { x: 0, stroke: "var(--border)", strokeWidth: 1.5 }), _jsx(ChartTooltip, { cursor: false, content: _jsx(ChartTooltipContent, { indicator: "line", labelFormatter: (_label, payload) => {
83
+ return (_jsx(ChartCard, { title: title, period: period, controls: controls, ...(link ? { link } : {}), summary: summary, aside: aside, ...(footer ? { footer } : {}), ...(headingLevel ? { headingLevel } : {}), className: className, children: (titleId) => emptyState && data.length === 0 ? (emptyState) : (_jsx(ChartContainer, { config: chartConfig, className: chartPlotClassName(size), children: _jsxs(BarChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: signedData, layout: "vertical", margin: { left: 8, right: 16 }, children: [_jsx(CartesianGrid, { horizontal: false, strokeDasharray: "3 3" }), _jsx(XAxis, { type: "number", domain: axis.domain, ticks: axis.ticks, tickLine: false, axisLine: false, tickMargin: 8, tickFormatter: (value) => (axisFormatter ?? valueFormatter)(Number(value)) }), _jsx(YAxis, { type: "category", dataKey: xKey, width: categoryAxisWidth(data, xKey), interval: 0, tick: CategoryTick, tickLine: false, axisLine: false, tickMargin: 8 }), _jsx(ReferenceLine, { x: 0, stroke: "var(--border)", strokeWidth: 1.5 }), _jsx(ChartTooltip, { cursor: false, content: _jsx(ChartTooltipContent, { indicator: "line", labelFormatter: (_label, payload) => {
75
84
  const exact = categoryDisplayKey
76
85
  ? payload?.[0]?.payload?.[categoryDisplayKey]
77
86
  : undefined;
@@ -9,6 +9,6 @@ import { type ChartCardProps } from "./chart-card.js";
9
9
  * @words Series named in full: "Monthly recurring revenue", "Model cost". Months as short names on the axis, the full month in the tooltip.
10
10
  * @access The plot is named by its title; each bar's figure is in the tooltip and, where the page needs it, a table.
11
11
  */
12
- declare function ChartBarMultiple({ title, period, controls, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter, axisFormatter, otherLabel, emptyState, size, className, }: ChartCardProps): import("react").JSX.Element;
12
+ declare function ChartBarMultiple({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter, axisFormatter, otherLabel, emptyState, size, className, }: ChartCardProps): import("react").JSX.Element;
13
13
  export { ChartBarMultiple };
14
14
  //# sourceMappingURL=chart-bar-multiple.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"chart-bar-multiple.d.ts","sourceRoot":"","sources":["../../src/components/chart-bar-multiple.tsx"],"names":[],"mappings":"AAcA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;;GASG;AACH,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,UAAU,EACV,IAAgB,EAChB,SAAS,GACV,EAAE,cAAc,+BAgEhB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"chart-bar-multiple.d.ts","sourceRoot":"","sources":["../../src/components/chart-bar-multiple.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;;GASG;AACH,iBAAS,gBAAgB,CAAC,EACxB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,UAAU,EACV,IAAgB,EAChB,SAAS,GACV,EAAE,cAAc,+BAuEhB;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -4,7 +4,7 @@
4
4
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts";
6
6
  import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, } from "./chart.js";
7
- import { CHART_Y_AXIS_TICK_COUNT, niceAxisTicks, seriesAxisMax } from "./chart-axis.js";
7
+ import { CHART_X_AXIS_TICKS, CHART_Y_AXIS_TICK_COUNT, niceAxisTicks, seriesAxisMax, } from "./chart-axis.js";
8
8
  import { CHART_LEGEND_CLASS, ChartCard, chartPlotClassName, chartSeriesConfig, defaultValueFormatter, foldOtherSeries, } from "./chart-card.js";
9
9
  import { entityColor } from "./chart-entity-colors.js";
10
10
  /**
@@ -17,11 +17,11 @@ import { entityColor } from "./chart-entity-colors.js";
17
17
  * @words Series named in full: "Monthly recurring revenue", "Model cost". Months as short names on the axis, the full month in the tooltip.
18
18
  * @access The plot is named by its title; each bar's figure is in the tooltip and, where the page needs it, a table.
19
19
  */
20
- function ChartBarMultiple({ title, period, controls, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter = defaultValueFormatter, axisFormatter, otherLabel, emptyState, size = "default", className, }) {
20
+ function ChartBarMultiple({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter = defaultValueFormatter, axisFormatter, otherLabel, emptyState, size = "default", className, }) {
21
21
  const folded = foldOtherSeries(series, data, entityColorMap, otherLabel);
22
22
  const chartConfig = chartSeriesConfig(folded.series, entityColorMap);
23
23
  const domainMax = seriesAxisMax(folded.data, folded.series.map((entry) => entry.id));
24
- return (_jsx(ChartCard, { title: title, period: period, controls: controls, summary: summary, aside: aside, ...(footer ? { footer } : {}), ...(headingLevel ? { headingLevel } : {}), className: className, children: (titleId) => emptyState && data.length === 0 ? (emptyState) : (_jsx(ChartContainer, { config: chartConfig, className: chartPlotClassName(size), children: _jsxs(BarChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: folded.data, children: [_jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: xKey, tickLine: false, tickMargin: 10, axisLine: false }), _jsx(YAxis, { width: "auto", tickLine: false, axisLine: false, tickMargin: 8, tickCount: CHART_Y_AXIS_TICK_COUNT, ...(domainMax === undefined
24
+ return (_jsx(ChartCard, { title: title, period: period, controls: controls, ...(link ? { link } : {}), summary: summary, aside: aside, ...(footer ? { footer } : {}), ...(headingLevel ? { headingLevel } : {}), className: className, children: (titleId) => emptyState && data.length === 0 ? (emptyState) : (_jsx(ChartContainer, { config: chartConfig, className: chartPlotClassName(size), children: _jsxs(BarChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: folded.data, children: [_jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: xKey, tickLine: false, tickMargin: 10, axisLine: false, ...CHART_X_AXIS_TICKS }), _jsx(YAxis, { width: "auto", tickLine: false, axisLine: false, tickMargin: 8, tickCount: CHART_Y_AXIS_TICK_COUNT, ...(domainMax === undefined
25
25
  ? {}
26
26
  : {
27
27
  domain: [0, domainMax],
@@ -9,7 +9,7 @@ import { type ChartCardProps } from "./chart-card.js";
9
9
  * @words Entity names as the reader knows them, never ids. The neutral remainder is "Everything else". Values through the page's shared money formatter.
10
10
  * @access The plot is an image named by the card title; the tooltip and legend are read with it. The share bar sits above the full-width table that carries each figure.
11
11
  */
12
- declare function ChartBarStacked({ title, period, controls, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter, axisFormatter, otherLabel, emptyState, size, share, className, }: ChartCardProps & {
12
+ declare function ChartBarStacked({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter, axisFormatter, otherLabel, emptyState, size, share, className, }: ChartCardProps & {
13
13
  /**
14
14
  * One bar across the card, each entity a segment of 100%: the share of a
15
15
  * total with no time axis. `data` is then a single row keyed by series id.
@@ -1 +1 @@
1
- {"version":3,"file":"chart-bar-stacked.d.ts","sourceRoot":"","sources":["../../src/components/chart-bar-stacked.tsx"],"names":[],"mappings":"AAcA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAmBjC;;;;;;;;;GASG;AACH,iBAAS,eAAe,CAAC,EACvB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,UAAU,EACV,IAAgB,EAChB,KAAa,EACb,SAAS,GACV,EAAE,cAAc,GAAG;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,+BAgGA;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"chart-bar-stacked.d.ts","sourceRoot":"","sources":["../../src/components/chart-bar-stacked.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAmBjC;;;;;;;;;GASG;AACH,iBAAS,eAAe,CAAC,EACvB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,cAAsC,EACtC,aAAa,EACb,UAAU,EACV,UAAU,EACV,IAAgB,EAChB,KAAa,EACb,SAAS,GACV,EAAE,cAAc,GAAG;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,+BAuGA;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -4,7 +4,7 @@
4
4
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts";
6
6
  import { ChartContainer, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, } from "./chart.js";
7
- import { CHART_Y_AXIS_TICK_COUNT, niceAxisTicks, stackedAxisMax } from "./chart-axis.js";
7
+ import { CHART_X_AXIS_TICKS, CHART_Y_AXIS_TICK_COUNT, niceAxisTicks, stackedAxisMax, } from "./chart-axis.js";
8
8
  import { CHART_LEGEND_CLASS, ChartCard, chartPlotClassName, chartSeriesConfig, defaultValueFormatter, foldOtherSeries, } from "./chart-card.js";
9
9
  import { entityColor } from "./chart-entity-colors.js";
10
10
  /** Stock stacked-bar corner radius: the bottom bar rounds down, the top bar up. */
@@ -37,11 +37,11 @@ function shareRadius(index, count) {
37
37
  * @words Entity names as the reader knows them, never ids. The neutral remainder is "Everything else". Values through the page's shared money formatter.
38
38
  * @access The plot is an image named by the card title; the tooltip and legend are read with it. The share bar sits above the full-width table that carries each figure.
39
39
  */
40
- function ChartBarStacked({ title, period, controls, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter = defaultValueFormatter, axisFormatter, otherLabel, emptyState, size = "default", share = false, className, }) {
40
+ function ChartBarStacked({ title, period, controls, link, summary, aside, footer, headingLevel, data, xKey, series, entityColorMap, valueFormatter = defaultValueFormatter, axisFormatter, otherLabel, emptyState, size = "default", share = false, className, }) {
41
41
  const folded = foldOtherSeries(series, data, entityColorMap, otherLabel);
42
42
  const chartConfig = chartSeriesConfig(folded.series, entityColorMap);
43
43
  const domainMax = stackedAxisMax(folded.data, folded.series.map((entry) => entry.id));
44
- return (_jsx(ChartCard, { title: title, period: period, controls: controls, summary: summary, aside: aside, ...(footer ? { footer } : {}), ...(headingLevel ? { headingLevel } : {}), className: className, children: (titleId) => emptyState && data.length === 0 ? (emptyState) : share ? (_jsx(ChartContainer, { config: chartConfig, className: "aspect-auto h-16 w-full", children: _jsxs(BarChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: folded.data, layout: "vertical", stackOffset: "expand", children: [_jsx(XAxis, { type: "number", hide: true }), _jsx(YAxis, { type: "category", dataKey: xKey, hide: true }), _jsx(ChartTooltip, { cursor: false, content: _jsx(ChartTooltipContent, { hideLabel: true, indicator: "line", valueFormatter: valueFormatter }) }), _jsx(ChartLegend, { itemSorter: null, content: _jsx(ChartLegendContent, { className: CHART_LEGEND_CLASS }) }), folded.series.map((entry, index) => (_jsx(Bar, { dataKey: entry.id, stackId: "a", fill: entityColor(entityColorMap, entry.id), radius: shareRadius(index, folded.series.length) }, entry.id)))] }) })) : (_jsx(ChartContainer, { config: chartConfig, className: chartPlotClassName(size), children: _jsxs(BarChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: folded.data, children: [_jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: xKey, tickLine: false, tickMargin: 10, axisLine: false }), _jsx(YAxis, { width: "auto", tickLine: false, axisLine: false, tickMargin: 8, tickCount: CHART_Y_AXIS_TICK_COUNT, ...(domainMax === undefined
44
+ return (_jsx(ChartCard, { title: title, period: period, controls: controls, ...(link ? { link } : {}), summary: summary, aside: aside, ...(footer ? { footer } : {}), ...(headingLevel ? { headingLevel } : {}), className: className, children: (titleId) => emptyState && data.length === 0 ? (emptyState) : share ? (_jsx(ChartContainer, { config: chartConfig, className: "aspect-auto h-16 w-full", children: _jsxs(BarChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: folded.data, layout: "vertical", stackOffset: "expand", children: [_jsx(XAxis, { type: "number", hide: true }), _jsx(YAxis, { type: "category", dataKey: xKey, hide: true }), _jsx(ChartTooltip, { cursor: false, content: _jsx(ChartTooltipContent, { hideLabel: true, indicator: "line", valueFormatter: valueFormatter }) }), _jsx(ChartLegend, { itemSorter: null, content: _jsx(ChartLegendContent, { className: CHART_LEGEND_CLASS }) }), folded.series.map((entry, index) => (_jsx(Bar, { dataKey: entry.id, stackId: "a", fill: entityColor(entityColorMap, entry.id), radius: shareRadius(index, folded.series.length) }, entry.id)))] }) })) : (_jsx(ChartContainer, { config: chartConfig, className: chartPlotClassName(size), children: _jsxs(BarChart, { accessibilityLayer: true, "aria-labelledby": titleId, data: folded.data, children: [_jsx(CartesianGrid, { strokeDasharray: "3 3" }), _jsx(XAxis, { dataKey: xKey, tickLine: false, tickMargin: 10, axisLine: false, ...CHART_X_AXIS_TICKS }), _jsx(YAxis, { width: "auto", tickLine: false, axisLine: false, tickMargin: 8, tickCount: CHART_Y_AXIS_TICK_COUNT, ...(domainMax === undefined
45
45
  ? {}
46
46
  : {
47
47
  domain: [0, domainMax],
@@ -25,13 +25,22 @@ type ChartSummaryProps = {
25
25
  trend?: ChartSummaryTrend;
26
26
  status?: React.ReactNode;
27
27
  };
28
- /** The footer strip: when the reading was taken, left; the way to its owner, right. */
28
+ /** The footer strip: when the reading was taken, left; a command on the reading itself, right. */
29
29
  type ChartCardFooter = {
30
30
  /** "Read at 12:42", "Updated 4 minutes ago". */
31
31
  reading: React.ReactNode;
32
- /** "Open in Analytics". */
32
+ /** A command on the reading, such as Refresh; the way to its owner is the header's `link`. */
33
33
  link?: PageCommand;
34
34
  };
35
+ /** The way to the reading's owner, at the header's trailing edge: OpenRouter's "Explore ›". */
36
+ type ChartCardLink = {
37
+ /** "Explore", "Open in Analytics". */
38
+ label: string;
39
+ /** Read instead of the label when it alone does not name the target: "Explore Usage by model". */
40
+ accessibleName?: string;
41
+ /** The app's link element, e.g. `<Link href="/analytics/explore?…" />`. */
42
+ link: React.ReactElement;
43
+ };
35
44
  type ChartCardProps = {
36
45
  /** Names the measure and its split: "Model spend by Customer". */
37
46
  title: React.ReactNode;
@@ -41,6 +50,8 @@ type ChartCardProps = {
41
50
  headingLevel?: 2 | 3 | 4;
42
51
  /** At the header's trailing edge: the metric `ToggleGroup`, and a period `Select` where the page has none. */
43
52
  controls?: React.ReactNode;
53
+ /** After the controls at the header's trailing edge: the way to the reading's owner. */
54
+ link?: ChartCardLink;
44
55
  /** A `ChartSummary` between the header and the plot. */
45
56
  summary?: React.ReactNode;
46
57
  /** A ranking beside the plot on wide cards, never a second card. */
@@ -86,11 +97,11 @@ declare function foldOtherSeries(series: readonly ChartSeries[], data: readonly
86
97
  * @family Charts
87
98
  * @when Every chart and every reading built around one: the frame a page never builds by hand. A chart is a named section of its page.
88
99
  * @instead A single figure is a `KpiCard`, never nested inside a chart. A ranking beside the plot goes in the card's `aside`, not a second card.
89
- * @behaviour Header grid: title and period in the first column, controls in the second from a 28 rem card width, under the title below it. Summary, plot, legend, footer in that order. An empty dataset shows its `emptyState` in the plot's place. The footer is a recessed strip behind a hairline: the reading's time left, the link to its owner right.
90
- * @words Title names the measure and its split: "Model spend by Customer". Period as dates. Footer: the reading's time, "Updated 4 minutes ago" or "Read at 12:42", and the way to its owner, "Open in Analytics". Sentence case throughout.
100
+ * @behaviour Header grid: title and period in the first column, controls and then the link to the reading's owner (a small ghost button ending in a chevron, as OpenRouter's "Explore ›") in the second from a 28 rem card width, under the title below it; a link with no controls stays at the trailing edge at every width. Summary, plot, legend, footer in that order. An empty dataset shows its `emptyState` in the plot's place. The footer is a recessed strip behind a hairline: the reading's time left, a command on the reading (Refresh) right.
101
+ * @words Title names the measure and its split: "Model spend by Customer". Period as dates. The link: "Explore", or "Open in Analytics" where the owner is another page. Footer: the reading's time, "Updated 4 minutes ago" or "Read at 12:42". Sentence case throughout.
91
102
  * @access The title is a heading at the page's level (default 2) and labels the plot. The plot is focusable and shows the 2 px focus outline only on keyboard focus.
92
103
  */
93
- declare function ChartCard({ title, period, controls, summary, aside, footer, headingLevel, className, children, }: Pick<ChartCardProps, "title" | "period" | "controls" | "summary" | "aside" | "footer" | "headingLevel" | "className"> & {
104
+ declare function ChartCard({ title, period, controls, link, summary, aside, footer, headingLevel, className, children, }: Pick<ChartCardProps, "title" | "period" | "controls" | "link" | "summary" | "aside" | "footer" | "headingLevel" | "className"> & {
94
105
  /** Receives the title's id, which the plot takes as `aria-labelledby`. */
95
106
  children: (titleId: string) => React.ReactNode;
96
107
  }): React.JSX.Element;
@@ -106,5 +117,5 @@ declare const CHART_FOCUS_CLASS = "[&_.recharts-surface:focus-visible]:nc-focus-
106
117
  /** Legend below the plot, left-aligned, wrapping to a second line. */
107
118
  declare const CHART_LEGEND_CLASS = "flex-wrap justify-start";
108
119
  export { CHART_FOCUS_CLASS, CHART_LEGEND_CLASS, ChartCard, ChartSummary, chartPlotClassName, chartSeriesConfig, defaultValueFormatter, foldOtherSeries, };
109
- export type { ChartCardFooter, ChartCardProps, ChartCardSize, ChartDatum, ChartSeries, ChartSummaryProps, ChartSummaryTrend, };
120
+ export type { ChartCardFooter, ChartCardLink, ChartCardProps, ChartCardSize, ChartDatum, ChartSeries, ChartSummaryProps, ChartSummaryTrend, };
110
121
  //# sourceMappingURL=chart-card.d.ts.map