@nadicodeai/ui 12.1.102 → 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 (562) 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.js +2 -2
  5. package/dist/components/action-menu.d.ts +20 -19
  6. package/dist/components/action-menu.d.ts.map +1 -1
  7. package/dist/components/action-menu.js +22 -15
  8. package/dist/components/action-status.d.ts +14 -10
  9. package/dist/components/action-status.d.ts.map +1 -1
  10. package/dist/components/action-status.js +14 -10
  11. package/dist/components/activity-calendar.d.ts +3 -1
  12. package/dist/components/activity-calendar.d.ts.map +1 -1
  13. package/dist/components/activity-calendar.js +16 -2
  14. package/dist/components/activity-feed.d.ts +2 -2
  15. package/dist/components/activity-feed.d.ts.map +1 -1
  16. package/dist/components/activity-feed.js +14 -5
  17. package/dist/components/agent-card.d.ts +11 -5
  18. package/dist/components/agent-card.d.ts.map +1 -1
  19. package/dist/components/agent-card.js +13 -7
  20. package/dist/components/agent-list-row.js +1 -1
  21. package/dist/components/agent-orb-appearance.d.ts +7 -1
  22. package/dist/components/agent-orb-appearance.d.ts.map +1 -1
  23. package/dist/components/agent-orb-appearance.js +26 -0
  24. package/dist/components/agent-profile.d.ts +8 -7
  25. package/dist/components/agent-profile.d.ts.map +1 -1
  26. package/dist/components/agent-profile.js +6 -6
  27. package/dist/components/alert-dialog.d.ts +25 -16
  28. package/dist/components/alert-dialog.d.ts.map +1 -1
  29. package/dist/components/alert-dialog.js +30 -18
  30. package/dist/components/alert.d.ts +1 -1
  31. package/dist/components/avatar.d.ts +83 -17
  32. package/dist/components/avatar.d.ts.map +1 -1
  33. package/dist/components/avatar.js +89 -23
  34. package/dist/components/badge.d.ts +59 -8
  35. package/dist/components/badge.d.ts.map +1 -1
  36. package/dist/components/badge.js +57 -14
  37. package/dist/components/breadcrumb.d.ts +18 -7
  38. package/dist/components/breadcrumb.d.ts.map +1 -1
  39. package/dist/components/breadcrumb.js +37 -13
  40. package/dist/components/button-group.d.ts +12 -15
  41. package/dist/components/button-group.d.ts.map +1 -1
  42. package/dist/components/button-group.js +13 -17
  43. package/dist/components/button.d.ts +126 -23
  44. package/dist/components/button.d.ts.map +1 -1
  45. package/dist/components/button.js +164 -39
  46. package/dist/components/calendar.d.ts +26 -15
  47. package/dist/components/calendar.d.ts.map +1 -1
  48. package/dist/components/calendar.js +60 -46
  49. package/dist/components/card-row.d.ts +13 -5
  50. package/dist/components/card-row.d.ts.map +1 -1
  51. package/dist/components/card-row.js +24 -10
  52. package/dist/components/card.d.ts +6 -12
  53. package/dist/components/card.d.ts.map +1 -1
  54. package/dist/components/card.js +11 -16
  55. package/dist/components/carousel.d.ts +3 -3
  56. package/dist/components/carousel.d.ts.map +1 -1
  57. package/dist/components/carousel.js +7 -7
  58. package/dist/components/catalog-drawer.d.ts +7 -7
  59. package/dist/components/catalog-drawer.d.ts.map +1 -1
  60. package/dist/components/catalog-drawer.js +6 -6
  61. package/dist/components/chart-area-stacked.d.ts +1 -1
  62. package/dist/components/chart-area-stacked.d.ts.map +1 -1
  63. package/dist/components/chart-area-stacked.js +4 -4
  64. package/dist/components/chart-axis.d.ts +14 -1
  65. package/dist/components/chart-axis.d.ts.map +1 -1
  66. package/dist/components/chart-axis.js +11 -1
  67. package/dist/components/chart-bar-horizontal.d.ts +2 -2
  68. package/dist/components/chart-bar-horizontal.d.ts.map +1 -1
  69. package/dist/components/chart-bar-horizontal.js +14 -5
  70. package/dist/components/chart-bar-multiple.d.ts +1 -1
  71. package/dist/components/chart-bar-multiple.d.ts.map +1 -1
  72. package/dist/components/chart-bar-multiple.js +3 -3
  73. package/dist/components/chart-bar-stacked.d.ts +1 -1
  74. package/dist/components/chart-bar-stacked.d.ts.map +1 -1
  75. package/dist/components/chart-bar-stacked.js +3 -3
  76. package/dist/components/chart-card.d.ts +17 -6
  77. package/dist/components/chart-card.d.ts.map +1 -1
  78. package/dist/components/chart-card.js +11 -4
  79. package/dist/components/chart-date-range-control.d.ts +18 -9
  80. package/dist/components/chart-date-range-control.d.ts.map +1 -1
  81. package/dist/components/chart-date-range-control.js +43 -47
  82. package/dist/components/chart-sparkline.d.ts +4 -3
  83. package/dist/components/chart-sparkline.d.ts.map +1 -1
  84. package/dist/components/chart-sparkline.js +6 -5
  85. package/dist/components/check-counts.d.ts +44 -0
  86. package/dist/components/check-counts.d.ts.map +1 -0
  87. package/dist/components/check-counts.js +51 -0
  88. package/dist/components/checkbox.d.ts +39 -11
  89. package/dist/components/checkbox.d.ts.map +1 -1
  90. package/dist/components/checkbox.js +38 -11
  91. package/dist/components/choicebox.d.ts +96 -0
  92. package/dist/components/choicebox.d.ts.map +1 -0
  93. package/dist/components/choicebox.js +113 -0
  94. package/dist/components/clearable-input.d.ts +57 -0
  95. package/dist/components/clearable-input.d.ts.map +1 -0
  96. package/dist/components/clearable-input.js +58 -0
  97. package/dist/components/code-block.d.ts +77 -17
  98. package/dist/components/code-block.d.ts.map +1 -1
  99. package/dist/components/code-block.js +85 -15
  100. package/dist/components/collapsible.d.ts +27 -10
  101. package/dist/components/collapsible.d.ts.map +1 -1
  102. package/dist/components/collapsible.js +24 -9
  103. package/dist/components/collection-filters.d.ts +3 -1
  104. package/dist/components/collection-filters.d.ts.map +1 -1
  105. package/dist/components/collection-filters.js +7 -9
  106. package/dist/components/collection-page.d.ts +31 -10
  107. package/dist/components/collection-page.d.ts.map +1 -1
  108. package/dist/components/collection-page.js +14 -13
  109. package/dist/components/collection-search.d.ts +32 -10
  110. package/dist/components/collection-search.d.ts.map +1 -1
  111. package/dist/components/collection-search.js +24 -13
  112. package/dist/components/collection-sort.d.ts.map +1 -1
  113. package/dist/components/collection-sort.js +2 -2
  114. package/dist/components/collection-toolbar.d.ts +5 -2
  115. package/dist/components/collection-toolbar.d.ts.map +1 -1
  116. package/dist/components/collection-toolbar.js +7 -4
  117. package/dist/components/combobox.d.ts +97 -22
  118. package/dist/components/combobox.d.ts.map +1 -1
  119. package/dist/components/combobox.js +80 -28
  120. package/dist/components/command.d.ts +34 -21
  121. package/dist/components/command.d.ts.map +1 -1
  122. package/dist/components/command.js +33 -25
  123. package/dist/components/confirm-dialog.d.ts +23 -6
  124. package/dist/components/confirm-dialog.d.ts.map +1 -1
  125. package/dist/components/confirm-dialog.js +32 -13
  126. package/dist/components/context-menu.d.ts +14 -10
  127. package/dist/components/context-menu.d.ts.map +1 -1
  128. package/dist/components/context-menu.js +17 -12
  129. package/dist/components/copy-button.d.ts +5 -2
  130. package/dist/components/copy-button.d.ts.map +1 -1
  131. package/dist/components/copy-button.js +16 -8
  132. package/dist/components/data-table.d.ts +120 -54
  133. package/dist/components/data-table.d.ts.map +1 -1
  134. package/dist/components/data-table.js +163 -92
  135. package/dist/components/desktop-shell.d.ts +4 -2
  136. package/dist/components/desktop-shell.d.ts.map +1 -1
  137. package/dist/components/desktop-shell.js +3 -3
  138. package/dist/components/dialog.d.ts +63 -24
  139. package/dist/components/dialog.d.ts.map +1 -1
  140. package/dist/components/dialog.js +52 -31
  141. package/dist/components/disclosure-row.d.ts +1 -2
  142. package/dist/components/disclosure-row.d.ts.map +1 -1
  143. package/dist/components/disclosure-row.js +1 -2
  144. package/dist/components/disclosure.d.ts +1 -1
  145. package/dist/components/disclosure.js +1 -1
  146. package/dist/components/drawer.d.ts +33 -12
  147. package/dist/components/drawer.d.ts.map +1 -1
  148. package/dist/components/drawer.js +47 -35
  149. package/dist/components/dropdown-menu.d.ts +59 -14
  150. package/dist/components/dropdown-menu.d.ts.map +1 -1
  151. package/dist/components/dropdown-menu.js +58 -26
  152. package/dist/components/empty-state.d.ts +35 -12
  153. package/dist/components/empty-state.d.ts.map +1 -1
  154. package/dist/components/empty-state.js +35 -17
  155. package/dist/components/entry-scene.d.ts +4 -4
  156. package/dist/components/entry-scene.d.ts.map +1 -1
  157. package/dist/components/entry-scene.js +2 -2
  158. package/dist/components/field.d.ts +44 -14
  159. package/dist/components/field.d.ts.map +1 -1
  160. package/dist/components/field.js +49 -20
  161. package/dist/components/file-diff.d.ts.map +1 -1
  162. package/dist/components/file-diff.js +3 -4
  163. package/dist/components/form-dialog.d.ts +7 -7
  164. package/dist/components/form-dialog.d.ts.map +1 -1
  165. package/dist/components/form-dialog.js +13 -11
  166. package/dist/components/form-drawer.d.ts +10 -7
  167. package/dist/components/form-drawer.d.ts.map +1 -1
  168. package/dist/components/form-drawer.js +11 -10
  169. package/dist/components/gauge.d.ts +64 -0
  170. package/dist/components/gauge.d.ts.map +1 -0
  171. package/dist/components/gauge.js +73 -0
  172. package/dist/components/hover-card.d.ts +72 -14
  173. package/dist/components/hover-card.d.ts.map +1 -1
  174. package/dist/components/hover-card.js +51 -17
  175. package/dist/components/identity-mark.d.ts +8 -1
  176. package/dist/components/identity-mark.d.ts.map +1 -1
  177. package/dist/components/identity-mark.js +31 -5
  178. package/dist/components/input-group.d.ts +44 -21
  179. package/dist/components/input-group.d.ts.map +1 -1
  180. package/dist/components/input-group.js +74 -27
  181. package/dist/components/input.d.ts +64 -12
  182. package/dist/components/input.d.ts.map +1 -1
  183. package/dist/components/input.js +51 -15
  184. package/dist/components/item.d.ts +37 -15
  185. package/dist/components/item.d.ts.map +1 -1
  186. package/dist/components/item.js +41 -22
  187. package/dist/components/kbd.d.ts +49 -13
  188. package/dist/components/kbd.d.ts.map +1 -1
  189. package/dist/components/kbd.js +115 -16
  190. package/dist/components/kpi-card.d.ts +12 -4
  191. package/dist/components/kpi-card.d.ts.map +1 -1
  192. package/dist/components/kpi-card.js +13 -4
  193. package/dist/components/label.d.ts +17 -10
  194. package/dist/components/label.d.ts.map +1 -1
  195. package/dist/components/label.js +18 -11
  196. package/dist/components/library-shelf.d.ts +6 -6
  197. package/dist/components/library-shelf.d.ts.map +1 -1
  198. package/dist/components/library-shelf.js +5 -5
  199. package/dist/components/load-more-button.d.ts +35 -0
  200. package/dist/components/load-more-button.d.ts.map +1 -0
  201. package/dist/components/load-more-button.js +26 -0
  202. package/dist/components/message-notice.d.ts +8 -13
  203. package/dist/components/message-notice.d.ts.map +1 -1
  204. package/dist/components/message-notice.js +25 -22
  205. package/dist/components/middle-truncate.d.ts +33 -0
  206. package/dist/components/middle-truncate.d.ts.map +1 -0
  207. package/dist/components/middle-truncate.js +72 -0
  208. package/dist/components/multi-select.d.ts +94 -0
  209. package/dist/components/multi-select.d.ts.map +1 -0
  210. package/dist/components/multi-select.js +132 -0
  211. package/dist/components/native-select.d.ts +37 -13
  212. package/dist/components/native-select.d.ts.map +1 -1
  213. package/dist/components/native-select.js +27 -11
  214. package/dist/components/notice-banner.d.ts +17 -10
  215. package/dist/components/notice-banner.d.ts.map +1 -1
  216. package/dist/components/notice-banner.js +12 -11
  217. package/dist/components/numbered-steps.d.ts +10 -4
  218. package/dist/components/numbered-steps.d.ts.map +1 -1
  219. package/dist/components/numbered-steps.js +9 -7
  220. package/dist/components/object-page.d.ts +40 -14
  221. package/dist/components/object-page.d.ts.map +1 -1
  222. package/dist/components/object-page.js +12 -10
  223. package/dist/components/object-workspace.d.ts +29 -10
  224. package/dist/components/object-workspace.d.ts.map +1 -1
  225. package/dist/components/object-workspace.js +18 -8
  226. package/dist/components/overview-page.d.ts +2 -2
  227. package/dist/components/overview-page.d.ts.map +1 -1
  228. package/dist/components/overview-page.js +8 -7
  229. package/dist/components/page-actions.d.ts +28 -8
  230. package/dist/components/page-actions.d.ts.map +1 -1
  231. package/dist/components/page-actions.js +22 -25
  232. package/dist/components/page-header.d.ts +11 -4
  233. package/dist/components/page-header.d.ts.map +1 -1
  234. package/dist/components/page-header.js +10 -5
  235. package/dist/components/pending-label.d.ts +6 -5
  236. package/dist/components/pending-label.d.ts.map +1 -1
  237. package/dist/components/pending-label.js +14 -6
  238. package/dist/components/picture-label.d.ts +2 -2
  239. package/dist/components/picture-label.d.ts.map +1 -1
  240. package/dist/components/picture-label.js +3 -3
  241. package/dist/components/portal-sidebar-frame.d.ts +9 -21
  242. package/dist/components/portal-sidebar-frame.d.ts.map +1 -1
  243. package/dist/components/portal-sidebar-frame.js +13 -27
  244. package/dist/components/progress-checklist.d.ts +46 -0
  245. package/dist/components/progress-checklist.d.ts.map +1 -0
  246. package/dist/components/progress-checklist.js +46 -0
  247. package/dist/components/progress.d.ts +48 -8
  248. package/dist/components/progress.d.ts.map +1 -1
  249. package/dist/components/progress.js +92 -16
  250. package/dist/components/prose.d.ts +19 -0
  251. package/dist/components/prose.d.ts.map +1 -0
  252. package/dist/components/prose.js +29 -0
  253. package/dist/components/radio-group.d.ts +51 -12
  254. package/dist/components/radio-group.d.ts.map +1 -1
  255. package/dist/components/radio-group.js +42 -12
  256. package/dist/components/reading-column.js +1 -1
  257. package/dist/components/record-identity.d.ts +6 -5
  258. package/dist/components/record-identity.d.ts.map +1 -1
  259. package/dist/components/record-identity.js +12 -3
  260. package/dist/components/record-list.d.ts +117 -27
  261. package/dist/components/record-list.d.ts.map +1 -1
  262. package/dist/components/record-list.js +185 -55
  263. package/dist/components/record-time.d.ts +20 -7
  264. package/dist/components/record-time.d.ts.map +1 -1
  265. package/dist/components/record-time.js +38 -19
  266. package/dist/components/resizable.d.ts +7 -5
  267. package/dist/components/resizable.d.ts.map +1 -1
  268. package/dist/components/resizable.js +6 -6
  269. package/dist/components/scope-switcher.d.ts +2 -0
  270. package/dist/components/scope-switcher.d.ts.map +1 -1
  271. package/dist/components/scope-switcher.js +2 -2
  272. package/dist/components/scroll-area.d.ts +47 -11
  273. package/dist/components/scroll-area.d.ts.map +1 -1
  274. package/dist/components/scroll-area.js +72 -14
  275. package/dist/components/segmented-control.d.ts +82 -0
  276. package/dist/components/segmented-control.d.ts.map +1 -0
  277. package/dist/components/segmented-control.js +90 -0
  278. package/dist/components/select.d.ts +55 -15
  279. package/dist/components/select.d.ts.map +1 -1
  280. package/dist/components/select.js +62 -19
  281. package/dist/components/separator.d.ts +12 -5
  282. package/dist/components/separator.d.ts.map +1 -1
  283. package/dist/components/separator.js +11 -6
  284. package/dist/components/settings-facts.d.ts +34 -14
  285. package/dist/components/settings-facts.d.ts.map +1 -1
  286. package/dist/components/settings-facts.js +21 -12
  287. package/dist/components/settings-page.d.ts +4 -4
  288. package/dist/components/settings-page.js +5 -5
  289. package/dist/components/settings-section.d.ts +160 -34
  290. package/dist/components/settings-section.d.ts.map +1 -1
  291. package/dist/components/settings-section.js +92 -39
  292. package/dist/components/sheet.d.ts +47 -16
  293. package/dist/components/sheet.d.ts.map +1 -1
  294. package/dist/components/sheet.js +40 -19
  295. package/dist/components/sidebar-sections.d.ts +16 -12
  296. package/dist/components/sidebar-sections.d.ts.map +1 -1
  297. package/dist/components/sidebar-sections.js +30 -15
  298. package/dist/components/sidebar.d.ts +117 -21
  299. package/dist/components/sidebar.d.ts.map +1 -1
  300. package/dist/components/sidebar.js +180 -55
  301. package/dist/components/skeleton.d.ts +54 -8
  302. package/dist/components/skeleton.d.ts.map +1 -1
  303. package/dist/components/skeleton.js +44 -9
  304. package/dist/components/slider.d.ts +53 -11
  305. package/dist/components/slider.d.ts.map +1 -1
  306. package/dist/components/slider.js +71 -17
  307. package/dist/components/snippet.d.ts +57 -0
  308. package/dist/components/snippet.d.ts.map +1 -0
  309. package/dist/components/snippet.js +60 -0
  310. package/dist/components/sonner.d.ts +13 -14
  311. package/dist/components/sonner.d.ts.map +1 -1
  312. package/dist/components/sonner.js +25 -22
  313. package/dist/components/status-badge.d.ts +37 -11
  314. package/dist/components/status-badge.d.ts.map +1 -1
  315. package/dist/components/status-badge.js +63 -15
  316. package/dist/components/status-dot.d.ts +42 -11
  317. package/dist/components/status-dot.d.ts.map +1 -1
  318. package/dist/components/status-dot.js +40 -11
  319. package/dist/components/switch.d.ts +43 -12
  320. package/dist/components/switch.d.ts.map +1 -1
  321. package/dist/components/switch.js +42 -12
  322. package/dist/components/table-card.d.ts +21 -12
  323. package/dist/components/table-card.d.ts.map +1 -1
  324. package/dist/components/table-card.js +17 -9
  325. package/dist/components/table-layouts.d.ts +40 -8
  326. package/dist/components/table-layouts.d.ts.map +1 -1
  327. package/dist/components/table-layouts.js +52 -8
  328. package/dist/components/table-value.d.ts +4 -3
  329. package/dist/components/table-value.d.ts.map +1 -1
  330. package/dist/components/table-value.js +6 -5
  331. package/dist/components/table.d.ts +62 -25
  332. package/dist/components/table.d.ts.map +1 -1
  333. package/dist/components/table.js +62 -26
  334. package/dist/components/tabs.d.ts +86 -17
  335. package/dist/components/tabs.d.ts.map +1 -1
  336. package/dist/components/tabs.js +93 -22
  337. package/dist/components/text-link.d.ts +4 -1
  338. package/dist/components/text-link.d.ts.map +1 -1
  339. package/dist/components/text-link.js +4 -1
  340. package/dist/components/text-with-copy-button.d.ts +30 -0
  341. package/dist/components/text-with-copy-button.d.ts.map +1 -0
  342. package/dist/components/text-with-copy-button.js +32 -0
  343. package/dist/components/textarea.d.ts +40 -10
  344. package/dist/components/textarea.d.ts.map +1 -1
  345. package/dist/components/textarea.js +50 -11
  346. package/dist/components/theme-mode-switcher.d.ts +18 -1
  347. package/dist/components/theme-mode-switcher.d.ts.map +1 -1
  348. package/dist/components/theme-mode-switcher.js +20 -2
  349. package/dist/components/toggle-group.d.ts +28 -8
  350. package/dist/components/toggle-group.d.ts.map +1 -1
  351. package/dist/components/toggle-group.js +12 -6
  352. package/dist/components/toggle.d.ts +6 -3
  353. package/dist/components/toggle.d.ts.map +1 -1
  354. package/dist/components/toggle.js +10 -7
  355. package/dist/components/tooltip.d.ts +43 -12
  356. package/dist/components/tooltip.d.ts.map +1 -1
  357. package/dist/components/tooltip.js +45 -16
  358. package/dist/components/trend-badge.js +1 -1
  359. package/dist/components/update-card.js +1 -1
  360. package/dist/eslint/index.js +82 -0
  361. package/dist/eslint/rules/badge-is-static-label.js +93 -0
  362. package/dist/eslint/rules/button-icon-slot.js +102 -0
  363. package/dist/eslint/rules/button-link-for-navigation.js +146 -0
  364. package/dist/eslint/rules/button-no-aria-label-with-text.js +75 -0
  365. package/dist/eslint/rules/button-type-roles-only-in-buttons.js +83 -0
  366. package/dist/eslint/rules/choice-control-has-a-name.js +98 -0
  367. package/dist/eslint/rules/choice-group-in-fieldset.js +86 -0
  368. package/dist/eslint/rules/command-shortcut-single-owner.js +118 -0
  369. package/dist/eslint/rules/confirm-dialog-words.js +63 -0
  370. package/dist/eslint/rules/data-table-one-unsized-column.js +96 -0
  371. package/dist/eslint/rules/destructive-action-placement.js +69 -0
  372. package/dist/eslint/rules/disabled-choice-says-why.js +71 -0
  373. package/dist/eslint/rules/ellipsis-opens-a-dialog.js +110 -0
  374. package/dist/eslint/rules/input-group-owners.js +155 -0
  375. package/dist/eslint/rules/kbd-children-no-modifier-text.js +128 -0
  376. package/dist/eslint/rules/literal-text.js +41 -0
  377. package/dist/eslint/rules/middle-truncate-placement.js +69 -0
  378. package/dist/eslint/rules/no-bare-button-label.js +55 -0
  379. package/dist/eslint/rules/no-control-in-read-only-surface.js +106 -0
  380. package/dist/eslint/rules/no-hand-built-busy.js +104 -0
  381. package/dist/eslint/rules/no-hand-built-theme-picker.js +144 -0
  382. package/dist/eslint/rules/no-hand-built-tile.js +41 -0
  383. package/dist/eslint/rules/no-hand-formatted-date.js +87 -0
  384. package/dist/eslint/rules/no-hand-stacked-avatars.js +67 -0
  385. package/dist/eslint/rules/no-nested-collapse.js +60 -0
  386. package/dist/eslint/rules/no-search-in-form.js +47 -0
  387. package/dist/eslint/rules/no-shadcn-appearance-override.js +2 -16
  388. package/dist/eslint/rules/no-shell-prompt-in-snippet.js +74 -0
  389. package/dist/eslint/rules/no-stock-error-words.js +56 -0
  390. package/dist/eslint/rules/no-tooltip-around-labelled-field.js +72 -0
  391. package/dist/eslint/rules/no-weight-class-on-strong-in-type-role.js +57 -0
  392. package/dist/eslint/rules/one-submenu-level.js +43 -0
  393. package/dist/eslint/rules/one-toast-per-flow.js +91 -0
  394. package/dist/eslint/rules/option-count.js +167 -0
  395. package/dist/eslint/rules/page-command-link-not-render.js +43 -0
  396. package/dist/eslint/rules/progress-needs-name.js +57 -0
  397. package/dist/eslint/rules/settings-limit-in-footer.js +94 -0
  398. package/dist/eslint/rules/skeleton-in-region.js +80 -0
  399. package/dist/eslint/rules/sortable-heading-uses-sort.js +79 -0
  400. package/dist/eslint/rules/table-cell-inset-owner.js +107 -0
  401. package/dist/eslint/rules/tabs-selection-is-controlled.js +47 -0
  402. package/dist/eslint/rules/tooltip-only-arrow.js +38 -0
  403. package/dist/eslint/rules/tooltip-trigger-accessible-name.js +114 -0
  404. package/dist/eslint/strict-design-system.js +21 -7
  405. package/dist/index.d.ts +13 -13
  406. package/dist/index.d.ts.map +1 -1
  407. package/dist/index.js +12 -13
  408. package/dist/internal/assistant-ui/attachment.d.ts.map +1 -1
  409. package/dist/internal/assistant-ui/attachment.js +2 -2
  410. package/dist/internal/assistant-ui/reasoning.d.ts +1 -1
  411. package/dist/internal/assistant-ui/reasoning.d.ts.map +1 -1
  412. package/dist/internal/assistant-ui/tool-fallback.js +1 -1
  413. package/dist/internal/assistant-ui/tool-group.d.ts +1 -1
  414. package/dist/internal/assistant-ui/tool-group.d.ts.map +1 -1
  415. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts +2 -3
  416. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts.map +1 -1
  417. package/dist/internal/assistant-ui/tooltip-icon-button.js +1 -1
  418. package/dist/internal/catalog-list.js +2 -2
  419. package/dist/internal/collection-note.d.ts +23 -0
  420. package/dist/internal/collection-note.d.ts.map +1 -0
  421. package/dist/internal/collection-note.js +17 -0
  422. package/dist/internal/collection-rail.d.ts +57 -0
  423. package/dist/internal/collection-rail.d.ts.map +1 -0
  424. package/dist/internal/collection-rail.js +33 -0
  425. package/dist/internal/company-logo.d.ts +18 -0
  426. package/dist/internal/company-logo.d.ts.map +1 -0
  427. package/dist/internal/company-logo.js +14 -0
  428. package/dist/internal/control-name.d.ts +12 -0
  429. package/dist/internal/control-name.d.ts.map +1 -0
  430. package/dist/internal/control-name.js +1 -0
  431. package/dist/internal/diff-line.d.ts +9 -0
  432. package/dist/internal/diff-line.d.ts.map +1 -0
  433. package/dist/internal/diff-line.js +8 -0
  434. package/dist/internal/empty.d.ts +8 -4
  435. package/dist/internal/empty.d.ts.map +1 -1
  436. package/dist/internal/empty.js +14 -8
  437. package/dist/internal/field-frame.d.ts +33 -0
  438. package/dist/internal/field-frame.d.ts.map +1 -0
  439. package/dist/internal/field-frame.js +20 -0
  440. package/dist/internal/final-focus.d.ts +8 -0
  441. package/dist/internal/final-focus.d.ts.map +1 -0
  442. package/dist/internal/final-focus.js +10 -0
  443. package/dist/internal/footer-strip.d.ts.map +1 -1
  444. package/dist/internal/footer-strip.js +3 -1
  445. package/dist/internal/form-submit.d.ts +9 -5
  446. package/dist/internal/form-submit.d.ts.map +1 -1
  447. package/dist/internal/form-submit.js +31 -2
  448. package/dist/internal/input-box.d.ts +26 -0
  449. package/dist/internal/input-box.d.ts.map +1 -0
  450. package/dist/internal/input-box.js +59 -0
  451. package/dist/internal/menu-surface.d.ts +10 -3
  452. package/dist/internal/menu-surface.d.ts.map +1 -1
  453. package/dist/internal/menu-surface.js +10 -3
  454. package/dist/internal/notice.d.ts +25 -0
  455. package/dist/internal/notice.d.ts.map +1 -0
  456. package/dist/internal/notice.js +33 -0
  457. package/dist/internal/overlay-stem.d.ts +5 -0
  458. package/dist/internal/overlay-stem.d.ts.map +1 -0
  459. package/dist/internal/overlay-stem.js +7 -0
  460. package/dist/internal/phone-sheet.d.ts +4 -0
  461. package/dist/internal/phone-sheet.d.ts.map +1 -0
  462. package/dist/internal/phone-sheet.js +2 -0
  463. package/dist/internal/present-content.d.ts +3 -0
  464. package/dist/internal/present-content.d.ts.map +1 -0
  465. package/dist/internal/present-content.js +1 -0
  466. package/dist/internal/record-menu-items.d.ts +4 -3
  467. package/dist/internal/record-menu-items.d.ts.map +1 -1
  468. package/dist/internal/record-menu-items.js +21 -6
  469. package/dist/internal/settings-save.d.ts +9 -2
  470. package/dist/internal/settings-save.d.ts.map +1 -1
  471. package/dist/internal/settings-save.js +9 -6
  472. package/dist/internal/table-compact-line.d.ts +38 -0
  473. package/dist/internal/table-compact-line.d.ts.map +1 -0
  474. package/dist/internal/table-compact-line.js +35 -0
  475. package/dist/internal/title-when-cut.d.ts +8 -0
  476. package/dist/internal/title-when-cut.d.ts.map +1 -0
  477. package/dist/internal/title-when-cut.js +22 -0
  478. package/dist/internal/unsaved-guard.d.ts +18 -0
  479. package/dist/internal/unsaved-guard.d.ts.map +1 -0
  480. package/dist/internal/unsaved-guard.js +31 -0
  481. package/dist/lib/merge-tokens.generated.js +2 -2
  482. package/dist/showcase/foundations.d.ts.map +1 -1
  483. package/dist/showcase/foundations.js +10 -2
  484. package/dist/showcase/specimens/actions.d.ts +2 -0
  485. package/dist/showcase/specimens/actions.d.ts.map +1 -1
  486. package/dist/showcase/specimens/actions.js +30 -5
  487. package/dist/showcase/specimens/charts.d.ts.map +1 -1
  488. package/dist/showcase/specimens/charts.js +22 -13
  489. package/dist/showcase/specimens/choices.d.ts +14 -3
  490. package/dist/showcase/specimens/choices.d.ts.map +1 -1
  491. package/dist/showcase/specimens/choices.js +93 -13
  492. package/dist/showcase/specimens/compositions.d.ts.map +1 -1
  493. package/dist/showcase/specimens/compositions.js +136 -23
  494. package/dist/showcase/specimens/data.d.ts +12 -7
  495. package/dist/showcase/specimens/data.d.ts.map +1 -1
  496. package/dist/showcase/specimens/data.js +139 -35
  497. package/dist/showcase/specimens/feedback.d.ts +2 -0
  498. package/dist/showcase/specimens/feedback.d.ts.map +1 -1
  499. package/dist/showcase/specimens/feedback.js +39 -15
  500. package/dist/showcase/specimens/index.d.ts +20 -12
  501. package/dist/showcase/specimens/index.d.ts.map +1 -1
  502. package/dist/showcase/specimens/inputs.d.ts +4 -2
  503. package/dist/showcase/specimens/inputs.d.ts.map +1 -1
  504. package/dist/showcase/specimens/inputs.js +62 -19
  505. package/dist/showcase/specimens/menus.d.ts +0 -1
  506. package/dist/showcase/specimens/menus.d.ts.map +1 -1
  507. package/dist/showcase/specimens/menus.js +47 -17
  508. package/dist/showcase/specimens/navigation.d.ts +6 -4
  509. package/dist/showcase/specimens/navigation.d.ts.map +1 -1
  510. package/dist/showcase/specimens/navigation.js +61 -32
  511. package/dist/showcase/specimens/other.d.ts +1 -3
  512. package/dist/showcase/specimens/other.d.ts.map +1 -1
  513. package/dist/showcase/specimens/other.js +17 -13
  514. package/dist/showcase/specimens/status.d.ts +4 -1
  515. package/dist/showcase/specimens/status.d.ts.map +1 -1
  516. package/dist/showcase/specimens/status.js +64 -11
  517. package/dist/showcase/usage.generated.d.ts +1 -1
  518. package/dist/showcase/usage.generated.d.ts.map +1 -1
  519. package/dist/showcase/usage.generated.js +632 -544
  520. package/dist/standalone/index.js +1 -1
  521. package/dist/styles/components.css +13 -13
  522. package/dist/styles/globals.css +25 -0
  523. package/package.json +2 -3
  524. package/dist/components/approval-row.d.ts +0 -34
  525. package/dist/components/approval-row.d.ts.map +0 -1
  526. package/dist/components/approval-row.js +0 -27
  527. package/dist/components/channel-view.d.ts +0 -112
  528. package/dist/components/channel-view.d.ts.map +0 -1
  529. package/dist/components/channel-view.js +0 -84
  530. package/dist/components/dashboard-shell.d.ts +0 -51
  531. package/dist/components/dashboard-shell.d.ts.map +0 -1
  532. package/dist/components/dashboard-shell.js +0 -89
  533. package/dist/components/direction.d.ts +0 -2
  534. package/dist/components/direction.d.ts.map +0 -1
  535. package/dist/components/direction.js +0 -1
  536. package/dist/components/expandable-block.d.ts +0 -20
  537. package/dist/components/expandable-block.d.ts.map +0 -1
  538. package/dist/components/expandable-block.js +0 -32
  539. package/dist/components/form.d.ts +0 -42
  540. package/dist/components/form.d.ts.map +0 -1
  541. package/dist/components/form.js +0 -91
  542. package/dist/components/label-system.d.ts +0 -17
  543. package/dist/components/label-system.d.ts.map +0 -1
  544. package/dist/components/label-system.js +0 -21
  545. package/dist/components/memory-item.d.ts +0 -21
  546. package/dist/components/memory-item.d.ts.map +0 -1
  547. package/dist/components/memory-item.js +0 -18
  548. package/dist/components/menubar.d.ts +0 -43
  549. package/dist/components/menubar.d.ts.map +0 -1
  550. package/dist/components/menubar.js +0 -69
  551. package/dist/components/navigation-menu.d.ts +0 -26
  552. package/dist/components/navigation-menu.d.ts.map +0 -1
  553. package/dist/components/navigation-menu.js +0 -45
  554. package/dist/components/pagination.d.ts +0 -33
  555. package/dist/components/pagination.d.ts.map +0 -1
  556. package/dist/components/pagination.js +0 -41
  557. package/dist/components/plugin-slot-boundary.d.ts +0 -42
  558. package/dist/components/plugin-slot-boundary.d.ts.map +0 -1
  559. package/dist/components/plugin-slot-boundary.js +0 -41
  560. package/dist/components/status-row.d.ts +0 -32
  561. package/dist/components/status-row.d.ts.map +0 -1
  562. package/dist/components/status-row.js +0 -35
@@ -1,26 +1,80 @@
1
+ "use client";
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
2
4
  import { Slider as SliderPrimitive } from "@base-ui/react/slider";
5
+ import { Input } from "./input.js";
3
6
  import { cn } from "../lib/utils.js";
7
+ function snapToStep(value, min, max, step) {
8
+ const stepped = min + Math.round((value - min) / step) * step;
9
+ return Math.min(max, Math.max(min, Number(stepped.toFixed(10))));
10
+ }
11
+ function SliderValueInput({ label, value, lower, upper, min, max, step, disabled, onCommit, }) {
12
+ const [draft, setDraft] = React.useState(null);
13
+ const commit = () => {
14
+ if (draft === null)
15
+ return;
16
+ setDraft(null);
17
+ const typed = Number(draft);
18
+ if (draft.trim() === "" || !Number.isFinite(typed))
19
+ return;
20
+ onCommit(Math.min(upper, Math.max(lower, snapToStep(typed, min, max, step))));
21
+ };
22
+ return (_jsx(Input, { "aria-label": label, className: "w-12 tabular-nums", "data-slot": "slider-input", disabled: disabled, inputMode: "decimal", onBlur: commit, onChange: (event) => setDraft(event.target.value), onKeyDown: (event) => {
23
+ if (event.key === "Enter")
24
+ commit();
25
+ }, size: "sm", value: draft ?? String(value) }));
26
+ }
4
27
  /**
5
- * A bounded number chosen by a thumb's position on a track.
28
+ * A bounded number chosen by a thumb's position on a track, with its name and its live value.
6
29
  *
7
30
  * @family Inputs
8
- * @when A bounded number where the position matters more than the digit: a limit, a share.
9
- * @instead An exact number is `Input`; pair the two when precision counts. A few named levels are
10
- * radios.
11
- * @behaviour A 4 px track, the filled part in ink, a 12 px thumb edged in the input grey. Hover,
12
- * drag and focus outline the thumb. Arrows step, Page Up and Down jump, Home and End reach the
13
- * bounds. The thumb's touch target is 44 px.
14
- * @words The label names the quantity; the current value and its unit are always written beside it
15
- * (*€ 400*). The help states the bounds and the step.
16
- * @access `role="slider"` with a name, min, max and `aria-valuetext` carrying the unit.
31
+ * @when "Use a slider for ranged numeric input where shape and proximity matter more than
32
+ * precision: bandwidth caps, opacity, audio volume, color channels."
33
+ * (https://vercel.com/geist/slider) Ours: a limit, a share.
34
+ * @instead "For exact values like a port number or memory limit, pair the slider with a numeric
35
+ * `Input`; keyboard users default to typing." (https://vercel.com/geist/slider) Ours:
36
+ * `showEndInput`, and `showStartInput` on a range, add that box. A few named levels are radios.
37
+ * @behaviour "Snap to a sensible step (`1`, `5`, `10%`) so dragging never produces values like
38
+ * `47.83291`." (https://vercel.com/geist/slider) "Clamp `min` and `max` to real product limits."
39
+ * (https://vercel.com/geist/slider) "Always render the live value next to the track in tabular
40
+ * nums, and label what the number represents (`Sample Rate · 44 kHz`)."
41
+ * (https://vercel.com/geist/slider) "The track alone is not self-describing."
42
+ * (https://vercel.com/geist/slider) "Threshold colors (warning, error tints past a limit) should
43
+ * match the same numeric breakpoint surfaced elsewhere in the UI; don’t invent a slider-only
44
+ * threshold." (https://vercel.com/geist/slider) Ours: `label`, `min`, `max` and `step` are
45
+ * required. The label sits above the track at 13 px in the secondary grey, with the live value
46
+ * beside it. The track is 8 px high and grey, the filled part is blue, and the thumb is a 6 by 14
47
+ * px white bar; a disabled slider turns the filled part grey and leaves the rest. Colour: blue is
48
+ * the one hue, the filled part and nothing else. The thumb grows by a fifth while it is dragged
49
+ * (only the dragged one) or has keyboard focus, and hovering changes nothing. A range has two
50
+ * thumbs and cannot cross. A typed value is snapped to the step and kept inside the bounds when the
51
+ * box loses focus or Enter is pressed. `onValueCommitted` fires once when the change settles.
52
+ * @words Ours: the label names the quantity: *Monthly limit*. The unit comes from `format`, so the
53
+ * value reads *€400*, not 400. The help under the slider states the bounds and the step.
54
+ * @access "Give the slider an accessible name through a sibling `<label htmlFor>` or `aria-label`,
55
+ * and let the native arrow-key, Page Up/Down, Home/End behavior do the keyboard work."
56
+ * (https://vercel.com/geist/slider) "Don’t intercept those keys." (https://vercel.com/geist/slider)
57
+ * Ours: each thumb is `role="slider"` named by the label, with `aria-valuetext` carrying the unit
58
+ * from `format`. A single thumb and its box are named by the label; the two thumbs and the two
59
+ * boxes of a range by the label and their position, *Price 1* and *Price 2*.
17
60
  */
18
- function Slider({ className, defaultValue, value, min = 0, max = 100, ...props }) {
19
- const _values = Array.isArray(value)
20
- ? value
21
- : Array.isArray(defaultValue)
22
- ? defaultValue
23
- : [min, max];
24
- return (_jsx(SliderPrimitive.Root, { className: cn("data-horizontal:w-full data-vertical:h-full", className), "data-slot": "slider", defaultValue: defaultValue, value: value, min: min, max: max, thumbAlignment: "edge", ...props, children: _jsxs(SliderPrimitive.Control, { className: "relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col", children: [_jsx(SliderPrimitive.Track, { "data-slot": "slider-track", className: "relative grow overflow-hidden rounded-full bg-muted select-none data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1", children: _jsx(SliderPrimitive.Indicator, { "data-slot": "slider-range", className: "bg-primary select-none data-horizontal:h-full data-vertical:w-full" }) }), Array.from({ length: _values.length }, (_, index) => (_jsx(SliderPrimitive.Thumb, { "data-slot": "slider-thumb", className: "relative block size-3 shrink-0 rounded-full border border-input bg-background transition-colors select-none after:absolute after:top-1/2 after:left-1/2 after:size-touch-target after:-translate-x-1/2 after:-translate-y-1/2 hover:nc-focus-outline active:nc-focus-outline disabled:pointer-events-none disabled:opacity-50 [@media(hover:hover)_and_(pointer:fine)]:after:hidden" }, index)))] }) }));
61
+ function Slider({ label, value, defaultValue, onValueChange, onValueCommitted, showStartInput, showEndInput, className, min, max, step, disabled, ...props }) {
62
+ const [internal, setInternal] = React.useState(defaultValue ?? [min]);
63
+ const values = value ?? internal;
64
+ const last = values.length - 1;
65
+ // SAFETY: Base UI returns one number per thumb, so a change keeps the length of the values it was given.
66
+ const asValues = (next) => next;
67
+ const change = (next) => {
68
+ setInternal(next);
69
+ onValueChange?.(asValues(next));
70
+ };
71
+ const commit = (next) => onValueCommitted?.(asValues(next));
72
+ const thumbName = values.length > 1 ? (index) => `${label} ${index + 1}` : undefined;
73
+ const input = (index) => (_jsx(SliderValueInput, { disabled: disabled, label: values.length > 1 ? `${label} ${index + 1}` : label, lower: index > 0 ? (values[index - 1] ?? min) : min, max: max, min: min, onCommit: (typed) => {
74
+ const next = values.map((current, position) => (position === index ? typed : current));
75
+ change(next);
76
+ commit(next);
77
+ }, step: step, upper: index < last ? (values[index + 1] ?? max) : max, value: values[index] ?? min }));
78
+ return (_jsxs(SliderPrimitive.Root, { className: cn("grid w-full gap-2 data-disabled:cursor-not-allowed", className), "data-slot": "slider", disabled: disabled, max: max, min: min, onValueChange: change, onValueCommitted: commit, step: step, thumbAlignment: "edge", value: values, ...props, children: [_jsxs("div", { className: "flex items-baseline justify-between gap-3", children: [_jsx(SliderPrimitive.Label, { className: "text-label-sm text-muted-foreground", children: label }), _jsx(SliderPrimitive.Value, { className: "text-label-sm text-muted-foreground tabular-nums" })] }), _jsxs("div", { className: "flex items-center gap-3", children: [showStartInput ? input(0) : null, _jsxs(SliderPrimitive.Control, { className: "relative flex w-full flex-1 touch-none items-center select-none", children: [_jsx(SliderPrimitive.Track, { "data-slot": "slider-track", className: "relative h-2 w-full grow overflow-hidden rounded-full bg-border select-none", children: _jsx(SliderPrimitive.Indicator, { "data-slot": "slider-range", className: "h-full bg-info select-none data-disabled:bg-muted-foreground/30" }) }), values.map((_, index) => (_jsx(SliderPrimitive.Thumb, { "data-slot": "slider-thumb", getAriaLabel: thumbName, getAriaValueText: (formatted) => formatted, index: index, className: "relative block h-3.5 w-1.5 shrink-0 rounded-xs border border-input bg-background nc-transition-transform select-none after:absolute after:top-1/2 after:left-1/2 after:size-touch-target after:-translate-x-1/2 after:-translate-y-1/2 data-disabled:pointer-events-none data-dragging:has-focus:scale-120 has-focus-visible:scale-120 has-focus-visible:nc-focus-outline has-focus-visible:outline-ring [@media(hover:hover)_and_(pointer:fine)]:after:hidden" }, index)))] }), showEndInput ? input(last) : null] })] }));
25
79
  }
26
80
  export { Slider };
@@ -0,0 +1,57 @@
1
+ import type { ReactElement } from "react";
2
+ import { type CopyButtonProps } from "./copy-button.js";
3
+ type SnippetContent = {
4
+ text: string | readonly string[];
5
+ copyText?: undefined;
6
+ placeholder?: undefined;
7
+ } | {
8
+ text: ReactElement;
9
+ copyText: string;
10
+ placeholder?: undefined;
11
+ } | {
12
+ text: "";
13
+ placeholder: string;
14
+ copyText?: undefined;
15
+ };
16
+ type SnippetVariant = "default" | "inverted" | "info" | "warning" | "destructive";
17
+ type SnippetProps = SnippetContent & {
18
+ variant?: SnippetVariant | undefined;
19
+ prompt?: boolean | undefined;
20
+ copied?: boolean | undefined;
21
+ onCopy?: (() => void) | undefined;
22
+ className?: string | undefined;
23
+ } & Pick<CopyButtonProps, "copyLabel" | "copiedLabel" | "copyFailedLabel">;
24
+ /**
25
+ * One command a person copies and runs in a terminal.
26
+ *
27
+ * @family Data
28
+ * @when “Use Snippet for a runnable shell command the user is meant to copy. For inline tokens (env var names, paths) use `InlineCode`, and for multi-line source use `CodeBlock`.” (https://vercel.com/geist/snippet)
29
+ * Ours: a command or a short sequence of commands to paste into a terminal: an install, a sign-in, a
30
+ * pairing step.
31
+ * @instead Ours: a value that is not a command (an identifier, a URL, a checksum) is `TextWithCopyButton`. A
32
+ * script someone reads before running is a `CodeBlock`. A token inside a sentence is inline code.
33
+ * @behaviour “Pass the command as `text`. Authors never type a leading `$`; the component renders the prompt, so `text="$ vercel deploy"` displays as `$ $ vercel deploy`.” (https://vercel.com/geist/snippet)
34
+ * “Set `prompt={false}` for non-shell content (URLs, JSON, output you want copied verbatim) so the rendered string matches what gets copied.” (https://vercel.com/geist/snippet)
35
+ * “Keep one command per Snippet. Pass an array to `text` for a short multi-line block; for longer scripts, switch to `CodeBlock` so users can read before they copy.” (https://vercel.com/geist/snippet)
36
+ * “Use `copyText` only when `text` contains rich nodes (`<span>` highlights, conditional fragments) and the clipboard payload should be plain text. For a string `text`, `copyText` is redundant.” (https://vercel.com/geist/snippet)
37
+ * “Use the `copied` prop to control the copy button animation externally. This lets you copy different text (e.g. from a context card) while reusing the snippet's checkmark feedback.” (https://vercel.com/geist/snippet)
38
+ * “Use `copied` plus an `onCopy` callback when a parent surface (a card, a tooltip) needs to show the same checkmark feedback while copying different text.” (https://vercel.com/geist/snippet)
39
+ * Ours: an array of strings is copied joined by line breaks, one row each after its own prompt; the
40
+ * prompt is never copied. The shell is as wide as its text, up to its row (`className="w-full"`
41
+ * fills the row); a longer line scrolls sideways with no scrollbar. `text=""` with a `placeholder`
42
+ * shows the placeholder, copies nothing and has no button. `text` that is an element needs
43
+ * `copyText`; a string needs none. `onCopy` reports a copy once the clipboard confirms. `variant`
44
+ * puts one colour on the whole shell, its text and the copy mark together: `info`, `warning` or
45
+ * `destructive` for a command inside a note of that kind, `inverted` for a dark block on a light
46
+ * page; the default is neutral, which is what almost every snippet is. Hovering the copy mark dims
47
+ * it and draws a 1 px ring; it never takes a fill or leaves the shell's text colour.
48
+ * @words “Pair `placeholder` with `text=""` for an empty state. Sentence case, no trailing period, no `Please`: `Run vercel link to fetch env vars`. The placeholder is informational, not copied.” (https://vercel.com/geist/snippet)
49
+ * Ours: the command as typed. The placeholder example is *Run nadia login to connect this computer*.
50
+ * `copyLabel` names the command (*Copy install command*); `copiedLabel` and `copyFailedLabel` are
51
+ * required with it.
52
+ * @access Ours: the text is read as text; the prompt is hidden from assistive technology. The button is
53
+ * named by `copyLabel`, and the result is read once from its status.
54
+ */
55
+ declare function Snippet(props: SnippetProps): import("react").JSX.Element;
56
+ export { Snippet, type SnippetProps };
57
+ //# sourceMappingURL=snippet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snippet.d.ts","sourceRoot":"","sources":["../../src/components/snippet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAG5E,KAAK,cAAc,GACf;IACE,IAAI,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,GACD;IACE,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;CACzB,GACD;IACE,IAAI,EAAE,EAAE,CAAC;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEN,KAAK,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAElF,KAAK,YAAY,GAAG,cAAc,GAAG;IACnC,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,aAAa,GAAG,iBAAiB,CAAC,CAAC;AAuB3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,iBAAS,OAAO,CAAC,KAAK,EAAE,YAAY,+BA8DnC;AAED,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,CAAC"}
@@ -0,0 +1,60 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { CopyButton } from "./copy-button.js";
4
+ import { cn } from "../lib/utils.js";
5
+ const SHELL = {
6
+ default: "border-border bg-background",
7
+ inverted: "border-border bg-foreground text-background",
8
+ info: "border-info/30 bg-info-soft text-info-soft-foreground",
9
+ warning: "border-warning/50 bg-warning-soft text-warning-soft-foreground",
10
+ destructive: "border-destructive/30 bg-destructive-soft text-destructive-soft-foreground",
11
+ };
12
+ const COPY_KEEPS_SHELL_COLOUR = "[&_[data-slot=button]]:hover:bg-transparent [&_[data-slot=button]]:hover:text-inherit [&_[data-slot=button]]:active:bg-transparent [&_[data-slot=button]]:active:text-inherit";
13
+ function copiedValue(content) {
14
+ if (content.copyText !== undefined)
15
+ return content.copyText;
16
+ return [content.text].flat().join("\n");
17
+ }
18
+ function linesOf(content) {
19
+ if (content.copyText !== undefined)
20
+ return [content.text];
21
+ return [content.text].flat();
22
+ }
23
+ /**
24
+ * One command a person copies and runs in a terminal.
25
+ *
26
+ * @family Data
27
+ * @when “Use Snippet for a runnable shell command the user is meant to copy. For inline tokens (env var names, paths) use `InlineCode`, and for multi-line source use `CodeBlock`.” (https://vercel.com/geist/snippet)
28
+ * Ours: a command or a short sequence of commands to paste into a terminal: an install, a sign-in, a
29
+ * pairing step.
30
+ * @instead Ours: a value that is not a command (an identifier, a URL, a checksum) is `TextWithCopyButton`. A
31
+ * script someone reads before running is a `CodeBlock`. A token inside a sentence is inline code.
32
+ * @behaviour “Pass the command as `text`. Authors never type a leading `$`; the component renders the prompt, so `text="$ vercel deploy"` displays as `$ $ vercel deploy`.” (https://vercel.com/geist/snippet)
33
+ * “Set `prompt={false}` for non-shell content (URLs, JSON, output you want copied verbatim) so the rendered string matches what gets copied.” (https://vercel.com/geist/snippet)
34
+ * “Keep one command per Snippet. Pass an array to `text` for a short multi-line block; for longer scripts, switch to `CodeBlock` so users can read before they copy.” (https://vercel.com/geist/snippet)
35
+ * “Use `copyText` only when `text` contains rich nodes (`<span>` highlights, conditional fragments) and the clipboard payload should be plain text. For a string `text`, `copyText` is redundant.” (https://vercel.com/geist/snippet)
36
+ * “Use the `copied` prop to control the copy button animation externally. This lets you copy different text (e.g. from a context card) while reusing the snippet's checkmark feedback.” (https://vercel.com/geist/snippet)
37
+ * “Use `copied` plus an `onCopy` callback when a parent surface (a card, a tooltip) needs to show the same checkmark feedback while copying different text.” (https://vercel.com/geist/snippet)
38
+ * Ours: an array of strings is copied joined by line breaks, one row each after its own prompt; the
39
+ * prompt is never copied. The shell is as wide as its text, up to its row (`className="w-full"`
40
+ * fills the row); a longer line scrolls sideways with no scrollbar. `text=""` with a `placeholder`
41
+ * shows the placeholder, copies nothing and has no button. `text` that is an element needs
42
+ * `copyText`; a string needs none. `onCopy` reports a copy once the clipboard confirms. `variant`
43
+ * puts one colour on the whole shell, its text and the copy mark together: `info`, `warning` or
44
+ * `destructive` for a command inside a note of that kind, `inverted` for a dark block on a light
45
+ * page; the default is neutral, which is what almost every snippet is. Hovering the copy mark dims
46
+ * it and draws a 1 px ring; it never takes a fill or leaves the shell's text colour.
47
+ * @words “Pair `placeholder` with `text=""` for an empty state. Sentence case, no trailing period, no `Please`: `Run vercel link to fetch env vars`. The placeholder is informational, not copied.” (https://vercel.com/geist/snippet)
48
+ * Ours: the command as typed. The placeholder example is *Run nadia login to connect this computer*.
49
+ * `copyLabel` names the command (*Copy install command*); `copiedLabel` and `copyFailedLabel` are
50
+ * required with it.
51
+ * @access Ours: the text is read as text; the prompt is hidden from assistive technology. The button is
52
+ * named by `copyLabel`, and the result is read once from its status.
53
+ */
54
+ function Snippet(props) {
55
+ const { className, copied, copiedLabel, copyFailedLabel, copyLabel, onCopy, prompt = true, variant = "default", } = props;
56
+ const value = copiedValue(props);
57
+ const empty = props.placeholder !== undefined;
58
+ return (_jsxs("div", { "data-slot": "snippet", "data-variant": variant, className: cn("relative flex w-fit max-w-full min-w-0 flex-col rounded-sm border py-2.5 pl-3 font-label-mono-md text-label-mono-md", empty ? "pr-3" : "pr-12", SHELL[variant], className), children: [_jsx("div", { className: "min-w-0 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden", children: empty ? (_jsx("span", { className: variant === "default" ? "text-placeholder" : "opacity-70", children: props.placeholder })) : (linesOf(props).map((line, index) => (_jsxs("div", { className: "flex gap-2 whitespace-pre", children: [prompt ? (_jsx("span", { "aria-hidden": "true", className: "select-none", children: "$" })) : null, _jsx("span", { children: line })] }, index)))) }), empty ? null : (_jsx("div", { className: cn("nc-transition-opacity absolute top-1/2 right-1 -translate-y-1/2 rounded-sm hover:opacity-80 hover:ring-1 hover:ring-border", COPY_KEEPS_SHELL_COLOUR), children: _jsx(CopyButton, { value: value, copyLabel: copyLabel, copiedLabel: copiedLabel, copyFailedLabel: copyFailedLabel, copied: copied, onCopy: onCopy, size: "icon-sm" }) }))] }));
59
+ }
60
+ export { Snippet };
@@ -1,22 +1,21 @@
1
1
  import { type ToasterProps } from "sonner";
2
+ type ToasterLabels = {
3
+ /** The close button's name: "Close notification". */
4
+ closeLabel: string;
5
+ /** The region's name, for a keyboard or screen reader user: "Notifications". */
6
+ regionLabel: string;
7
+ };
8
+ type ToasterOwnProps = Omit<ToasterProps, "closeButton" | "containerAriaLabel" | "duration" | "icons" | "toastOptions">;
2
9
  /**
3
10
  * The one place toasts appear, mounted once per product.
4
11
  *
5
12
  * @family Feedback
6
- * @when One acknowledgement of an action the person took, when the result is not already visible
7
- * where they are looking; and the Undo of a reversible removal. Mount it once; raise toasts through
8
- * `toast`.
9
- * @instead For a failure that must stay, use `MessageNotice` by the control. For unsaved work,
10
- * failed payment or lost access never a toast alone. For a condition use a banner.
11
- * @behaviour Tone `success`, `info`, `warning`, `error`; mark in the deep step. The first action
12
- * with a handler becomes its one button. Undo only where a safe rollback exists. A toast that stays
13
- * up shows the waiting line, not a spinner.
14
- * @words Completion is noun, past participle: *Mailbox removed*, *Agent created*, paired one to one
15
- * with its button *Remove mailbox*. No *successfully*, no exclamation.
16
- * @access Announced by the toaster's live region. Never the only route to recovery: the record's
17
- * own row keeps its controls. Undo is reachable by keyboard (Alt+T moves focus to the toasts) while
18
- * it shows.
13
+ * @when "A succinct message that is displayed temporarily." (https://vercel.com/geist/toast) "Use a toast for non-blocking acknowledgments of user-initiated actions: `Domain added`, `Project archived`, `Deployment canceled`." (https://vercel.com/geist/toast) "Pick the method by how the user experienced the event, not by HTTP status. A user-canceled deploy is `toasts.message('Deployment canceled')`, not `success`. A partial deploy with skipped routes is `toasts.warning(...)`." (https://vercel.com/geist/toast) Ours: mount it once and raise toasts through `showMessageToast`. `toasts.message` is the tone `info`, and `success`, `warning` and `error` keep their names.
14
+ * @instead "Don’t use a toast alone for billing failures, permission denials, or build failures the user has to triage. Pair a ≤6-word toast (`Build failed`) with a persistent row carrying the recovery step and a stable identifier." (https://vercel.com/geist/toast) "Field-level validation belongs on the `Input`, not in a toast. Persistent configuration warnings belong in `Note` or `Banner`." (https://vercel.com/geist/toast) Ours: the persistent row is a `MessageNotice`, a field's wrong value stays on the field (`FieldError`), and a lasting condition is a `NoticeBanner`.
15
+ * @behaviour "Default toasts auto-dismiss; pass `preserve` only when the user must read or act on the message before it disappears." (https://vercel.com/geist/toast) "Undo snackbars stay on screen for 5–10 seconds and pair the past-tense toast with a single `Undo` action button." (https://vercel.com/geist/toast) "Don’t stack toasts to narrate one async flow; emit the success or error toast at the terminal step." (https://vercel.com/geist/toast) Ours: `showMessageToast` takes no `preserve`, so every toast leaves after 6 s, which is also the Undo window; the first action with a handler becomes the toast's one button. Colour sits on the whole toast: `success` fills it with the accent blue (Geist's blue success, the same hue as an `info` note), `warning` and `error` with their solid colour, each with that colour's text; `info` stays the plain surface. The tone's mark stays, because a tone must read without colour and the hidden tone word Geist uses would need a word in the product's language that `showMessageToast` does not take. A toast is 420 px wide at most, 16 px padded, with a close button of 32 px at its trailing edge. A toast that stays up shows the waiting line, not a spinner. Required: `closeLabel` and `regionLabel`, because the close button and the region need a name in the product's language.
16
+ * @words "One sentence, sentence case, no trailing period when the toast is a single sentence." (https://vercel.com/geist/toast) "Completion toasts follow `{Noun} {past-participle}`: `Blob deleted`, `Domain added`, `Environment variable saved`. Never include `successfully`; the action name implies it." (https://vercel.com/geist/toast) "Error toasts are two sentences with periods and end with a recovery step: `Couldn’t verify domain. Try again.` Use `Couldn’t` for user-state errors and `Failed to` for system or infra errors; match adjacent shipped copy and don’t flip mid-flow." (https://vercel.com/geist/toast) "Pair the toast verb 1:1 with the destructive button verb (`Delete Project` then `Project deleted`, never `Project removed`)." (https://vercel.com/geist/toast) "Undo snackbars use the literal label `Undo`, never `Restore`, `Bring Back`, or `Cancel`. Only use the pattern when the rollback is safe." (https://vercel.com/geist/toast) Ours: the words come from the catalogue; *Mailbox removed* pairs with its button *Remove mailbox*.
17
+ * @access "The toast region announces with `aria-live="polite"`; reserve `assertive` for blocking errors that interrupt a flow." (https://vercel.com/geist/toast) "Don’t put primary navigation inside a toast; transient surfaces vanish before keyboard users can reach them." (https://vercel.com/geist/toast) Ours: the toaster's live region is named by `regionLabel` and the close button by `closeLabel`. Navigation is never the only route to recovery: the record's own row keeps its controls. Undo is reachable by keyboard (Alt+T moves focus to the toasts) while it shows.
19
18
  */
20
- declare const Toaster: ({ ...props }: ToasterProps) => import("react").JSX.Element;
19
+ declare const Toaster: ({ closeLabel, regionLabel, ...props }: ToasterOwnProps & ToasterLabels) => import("react").JSX.Element;
21
20
  export { Toaster };
22
21
  //# sourceMappingURL=sonner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sonner.d.ts","sourceRoot":"","sources":["../../src/components/sonner.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAM9D;;;;;;;;;;;;;;;;;GAiBG;AACH,QAAA,MAAM,OAAO,GAAI,cAAc,YAAY,gCAiC1C,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"sonner.d.ts","sourceRoot":"","sources":["../../src/components/sonner.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,QAAQ,CAAC;AAQ9D,KAAK,aAAa,GAAG;IACnB,qDAAqD;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,KAAK,eAAe,GAAG,IAAI,CACzB,YAAY,EACZ,aAAa,GAAG,oBAAoB,GAAG,UAAU,GAAG,OAAO,GAAG,cAAc,CAC7E,CAAC;AAEF;;;;;;;;;GASG;AACH,QAAA,MAAM,OAAO,GAAI,uCAAuC,eAAe,GAAG,aAAa,gCAiDtF,CAAC;AAEF,OAAO,EAAE,OAAO,EAAE,CAAC"}
@@ -2,47 +2,50 @@
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { useTheme } from "next-themes";
4
4
  import { Toaster as Sonner } from "sonner";
5
- import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon } from "lucide-react";
5
+ import { CircleCheckIcon, InfoIcon, OctagonXIcon, TriangleAlertIcon, XIcon } from "lucide-react";
6
6
  import { WaitingLine } from "./waiting-line.js";
7
7
  import { isThemeMode } from "../lib/theme-mode.js";
8
+ const TOAST_DURATION_MS = 6000;
8
9
  /**
9
10
  * The one place toasts appear, mounted once per product.
10
11
  *
11
12
  * @family Feedback
12
- * @when One acknowledgement of an action the person took, when the result is not already visible
13
- * where they are looking; and the Undo of a reversible removal. Mount it once; raise toasts through
14
- * `toast`.
15
- * @instead For a failure that must stay, use `MessageNotice` by the control. For unsaved work,
16
- * failed payment or lost access never a toast alone. For a condition use a banner.
17
- * @behaviour Tone `success`, `info`, `warning`, `error`; mark in the deep step. The first action
18
- * with a handler becomes its one button. Undo only where a safe rollback exists. A toast that stays
19
- * up shows the waiting line, not a spinner.
20
- * @words Completion is noun, past participle: *Mailbox removed*, *Agent created*, paired one to one
21
- * with its button *Remove mailbox*. No *successfully*, no exclamation.
22
- * @access Announced by the toaster's live region. Never the only route to recovery: the record's
23
- * own row keeps its controls. Undo is reachable by keyboard (Alt+T moves focus to the toasts) while
24
- * it shows.
13
+ * @when "A succinct message that is displayed temporarily." (https://vercel.com/geist/toast) "Use a toast for non-blocking acknowledgments of user-initiated actions: `Domain added`, `Project archived`, `Deployment canceled`." (https://vercel.com/geist/toast) "Pick the method by how the user experienced the event, not by HTTP status. A user-canceled deploy is `toasts.message('Deployment canceled')`, not `success`. A partial deploy with skipped routes is `toasts.warning(...)`." (https://vercel.com/geist/toast) Ours: mount it once and raise toasts through `showMessageToast`. `toasts.message` is the tone `info`, and `success`, `warning` and `error` keep their names.
14
+ * @instead "Don’t use a toast alone for billing failures, permission denials, or build failures the user has to triage. Pair a ≤6-word toast (`Build failed`) with a persistent row carrying the recovery step and a stable identifier." (https://vercel.com/geist/toast) "Field-level validation belongs on the `Input`, not in a toast. Persistent configuration warnings belong in `Note` or `Banner`." (https://vercel.com/geist/toast) Ours: the persistent row is a `MessageNotice`, a field's wrong value stays on the field (`FieldError`), and a lasting condition is a `NoticeBanner`.
15
+ * @behaviour "Default toasts auto-dismiss; pass `preserve` only when the user must read or act on the message before it disappears." (https://vercel.com/geist/toast) "Undo snackbars stay on screen for 5–10 seconds and pair the past-tense toast with a single `Undo` action button." (https://vercel.com/geist/toast) "Don’t stack toasts to narrate one async flow; emit the success or error toast at the terminal step." (https://vercel.com/geist/toast) Ours: `showMessageToast` takes no `preserve`, so every toast leaves after 6 s, which is also the Undo window; the first action with a handler becomes the toast's one button. Colour sits on the whole toast: `success` fills it with the accent blue (Geist's blue success, the same hue as an `info` note), `warning` and `error` with their solid colour, each with that colour's text; `info` stays the plain surface. The tone's mark stays, because a tone must read without colour and the hidden tone word Geist uses would need a word in the product's language that `showMessageToast` does not take. A toast is 420 px wide at most, 16 px padded, with a close button of 32 px at its trailing edge. A toast that stays up shows the waiting line, not a spinner. Required: `closeLabel` and `regionLabel`, because the close button and the region need a name in the product's language.
16
+ * @words "One sentence, sentence case, no trailing period when the toast is a single sentence." (https://vercel.com/geist/toast) "Completion toasts follow `{Noun} {past-participle}`: `Blob deleted`, `Domain added`, `Environment variable saved`. Never include `successfully`; the action name implies it." (https://vercel.com/geist/toast) "Error toasts are two sentences with periods and end with a recovery step: `Couldn’t verify domain. Try again.` Use `Couldn’t` for user-state errors and `Failed to` for system or infra errors; match adjacent shipped copy and don’t flip mid-flow." (https://vercel.com/geist/toast) "Pair the toast verb 1:1 with the destructive button verb (`Delete Project` then `Project deleted`, never `Project removed`)." (https://vercel.com/geist/toast) "Undo snackbars use the literal label `Undo`, never `Restore`, `Bring Back`, or `Cancel`. Only use the pattern when the rollback is safe." (https://vercel.com/geist/toast) Ours: the words come from the catalogue; *Mailbox removed* pairs with its button *Remove mailbox*.
17
+ * @access "The toast region announces with `aria-live="polite"`; reserve `assertive` for blocking errors that interrupt a flow." (https://vercel.com/geist/toast) "Don’t put primary navigation inside a toast; transient surfaces vanish before keyboard users can reach them." (https://vercel.com/geist/toast) Ours: the toaster's live region is named by `regionLabel` and the close button by `closeLabel`. Navigation is never the only route to recovery: the record's own row keeps its controls. Undo is reachable by keyboard (Alt+T moves focus to the toasts) while it shows.
25
18
  */
26
- const Toaster = ({ ...props }) => {
19
+ const Toaster = ({ closeLabel, regionLabel, ...props }) => {
27
20
  const { theme = "system" } = useTheme();
28
- return (_jsx(Sonner, { theme: isThemeMode(theme) ? theme : "system", className: "toaster group", icons: {
29
- success: _jsx(CircleCheckIcon, { className: "size-4 text-success-soft-foreground" }),
30
- info: _jsx(InfoIcon, { className: "size-4 text-info-soft-foreground" }),
31
- warning: _jsx(TriangleAlertIcon, { className: "size-4 text-warning-soft-foreground" }),
32
- error: _jsx(OctagonXIcon, { className: "size-4 text-destructive-soft-foreground" }),
21
+ return (_jsx(Sonner, { theme: isThemeMode(theme) ? theme : "system", className: "toaster group", closeButton: true, containerAriaLabel: regionLabel, duration: TOAST_DURATION_MS, icons: {
22
+ success: _jsx(CircleCheckIcon, { className: "size-4" }),
23
+ info: _jsx(InfoIcon, { className: "size-4" }),
24
+ warning: _jsx(TriangleAlertIcon, { className: "size-4" }),
25
+ error: _jsx(OctagonXIcon, { className: "size-4" }),
26
+ close: _jsx(XIcon, { className: "size-4" }),
33
27
  // A toast that stays up is already past a second, so its mark is the
34
28
  // one waiting line rather than a spinning glyph.
35
29
  loading: _jsx(WaitingLine, { className: "w-8", decorative: true }),
36
30
  },
37
31
  // SAFETY: CSSProperties lists only standard properties; React sets each `--` custom property key here through style.setProperty.
38
32
  style: {
39
- "--normal-bg": "var(--popover)",
33
+ "--normal-bg": "color-mix(in srgb, var(--popover) var(--nc-material-glass-opacity), transparent)",
40
34
  "--normal-text": "var(--popover-foreground)",
41
35
  "--normal-border": "transparent",
42
36
  "--border-radius": "var(--radius-lg)",
37
+ "--width": "420px",
43
38
  }, toastOptions: {
39
+ closeButtonAriaLabel: closeLabel,
44
40
  classNames: {
45
- toast: "nc-toast nc-elevation-floating",
41
+ toast: "nc-toast nc-glass nc-elevation-floating min-h-16 pr-16! text-body-sm!",
42
+ title: "font-normal!",
43
+ description: "text-current!",
44
+ closeButton: "top-4! right-4! left-auto! size-8! transform-none! rounded-sm! border-0! bg-transparent! opacity-100! hover:bg-current/10!",
45
+ actionButton: "h-nadicode-control-height-sm! rounded-sm! bg-primary! px-button-padding-inline-sm! text-button! font-medium! text-primary-foreground!",
46
+ success: "[--normal-bg:var(--info)] [--normal-text:var(--info-foreground)]",
47
+ warning: "[--normal-bg:var(--warning)] [--normal-text:var(--warning-foreground)]",
48
+ error: "[--normal-bg:var(--destructive)] [--normal-text:var(--destructive-foreground)]",
46
49
  },
47
50
  }, ...props }));
48
51
  };
@@ -1,8 +1,13 @@
1
1
  import type { ComponentProps } from "react";
2
+ import { type BadgeSize } from "./badge.js";
2
3
  type StatusBadgeTone = "success" | "warning" | "danger" | "info" | "neutral";
3
- type StatusBadgeProps = Omit<ComponentProps<"span">, "children"> & {
4
+ type StatusBadgeEmphasis = "subtle" | "solid";
5
+ type StatusBadgeProps = Omit<ComponentProps<"span">, "children" | "onClick"> & {
4
6
  tone: StatusBadgeTone;
5
7
  label: string;
8
+ size?: BadgeSize;
9
+ /** `subtle` in rows, tables, lists and menus; `solid` where the status stands on its own. */
10
+ emphasis?: StatusBadgeEmphasis;
6
11
  /** How long the status has held, set after the word in tabular figures. */
7
12
  since?: string;
8
13
  };
@@ -10,17 +15,38 @@ type StatusBadgeProps = Omit<ComponentProps<"span">, "children"> & {
10
15
  * A record's state: a mark and a word in one of five tones.
11
16
  *
12
17
  * @family Status
13
- * @when A record's state, when it sets the row apart: failed, waiting on a person, a step in
18
+ * @when "Use Badge for short, scannable metadata that sits next to the thing it describes: status, plan tier, environment, or role." (https://vercel.com/geist/badge)
19
+ * Ours: a record's state, when it sets the row apart: failed, waiting on a person, a step in
14
20
  * motion, paused, connected. Gray is every terminal state that needs no action.
15
- * @instead For a category (an installation, a partner) use `Tag`. For a control reporting its own
16
- * action use `ActionStatus`. For a mark beside a word that already names the state, `StatusDot`.
17
- * @behaviour Still: a status never moves and is never a button. Each app keeps one value-to-tone
18
- * map in one module; nothing else picks a status colour. A healthy record shows no badge.
19
- * @words A state, not a verb: *Failed*, *Waiting for you*. Sentence case, one to three words, no
21
+ * "Map meaning to color: `green` for healthy, `red` for error, `amber` for warning, `blue` for informational or production, `gray` for neutral." (https://vercel.com/geist/badge)
22
+ * Ours: success is green, danger red, warning amber, info blue, neutral gray, whatever the state's
23
+ * name, in our colour values. The tone and the word are required, and the type asks for both.
24
+ * @instead "For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot)
25
+ * Ours: that `Badge` is `StatusBadge`. For a category (an installation, a partner) use `Tag`. For
26
+ * plain metadata (a role, a plan) use `Badge`. For a control reporting its own action use
27
+ * `ActionStatus`. For a mark beside a word that already names the state, `StatusDot`.
28
+ * @behaviour "Badges are static labels." (https://vercel.com/geist/badge)
29
+ * "Don’t wire `onClick` onto them; promote to a Button or link if the user can act on the value." (https://vercel.com/geist/badge)
30
+ * Ours: a status never moves and is never a button.
31
+ * "The `-subtle` suffix tones any of them down on dense surfaces." (https://vercel.com/geist/badge)
32
+ * Ours: `subtle`, the default, is for rows, tables, lists and menus: it fills the pill with the
33
+ * tone's soft ground and sets the mark and the word in its strong shade; gray takes the foreground
34
+ * colour, never a muted one. `solid` is for a status that stands on its own, such as an object's
35
+ * page header or a card title: it fills the pill with the tone's strong colour and sets the mark
36
+ * and the word on it. No border and no ring either way.
37
+ * "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge)
38
+ * Ours: it always draws its tone's mark, even for success and error: the mark repeats the tone as a
39
+ * shape so a status reads without colour. Each app keeps one value-to-tone map in one module;
40
+ * nothing else picks a status colour. A healthy record shows no badge.
41
+ * @words "Title Case, one word when possible, two max: `Active`, `Pending`, `Pro`, `Enterprise Trial`." (https://vercel.com/geist/badge)
42
+ * Ours: a state, not a verb (*Failed*, *Waiting for you*), in sentence case, one to three words, no
20
43
  * trailing ellipsis. Italian runs a third longer: *In attesa di te*.
21
- * @access The word is the name; the mark is `aria-hidden` and repeats the tone as a shape, so
22
- * colour never carries the state alone. Not focusable.
44
+ * "Match the canonical API or log term: `Production` not `Prod`, `Deployed` not `Live`, `Canceled` not `Cancelled` (the Vercel API uses one L)." (https://vercel.com/geist/badge)
45
+ * "Skip stuffing sentences inside (`Currently Active`, `You are on Pro`); the surrounding row supplies the context." (https://vercel.com/geist/badge)
46
+ * @access "Don’t rely on color alone; the text has to be readable without it." (https://vercel.com/geist/badge)
47
+ * Ours: the word is the name; the mark is `aria-hidden`, so colour never carries the state alone.
48
+ * Not focusable.
23
49
  */
24
- declare function StatusBadge({ tone, label, since, className, ...props }: StatusBadgeProps): import("react").JSX.Element;
25
- export { StatusBadge, type StatusBadgeProps, type StatusBadgeTone };
50
+ declare function StatusBadge({ tone, label, since, className, size, emphasis, ...props }: StatusBadgeProps): import("react").JSX.Element;
51
+ export { StatusBadge, type StatusBadgeEmphasis, type StatusBadgeProps, type StatusBadgeTone };
26
52
  //# sourceMappingURL=status-badge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-badge.d.ts","sourceRoot":"","sources":["../../src/components/status-badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAM5C,KAAK,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAoB7E,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG;IACjE,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,iBAAS,WAAW,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,+BAmBjF;AAED,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"status-badge.d.ts","sourceRoot":"","sources":["../../src/components/status-badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAG5C,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG3D,KAAK,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE7E,KAAK,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CAAC;AAgD9C,KAAK,gBAAgB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,GAAG;IAC7E,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,iBAAS,WAAW,CAAC,EACnB,IAAI,EACJ,KAAK,EACL,KAAK,EACL,SAAS,EACT,IAAW,EACX,QAAmB,EACnB,GAAG,KAAK,EACT,EAAE,gBAAgB,+BAqBlB;AAED,OAAO,EAAE,WAAW,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,CAAC"}
@@ -3,11 +3,31 @@ import { CircleCheck, CircleDot, CirclePause, CircleX, Clock } from "lucide-reac
3
3
  import { Badge } from "./badge.js";
4
4
  import { cn } from "../lib/utils.js";
5
5
  const FILL_BY_TONE = {
6
- success: { name: "green", classes: "bg-success-soft text-success-soft-foreground" },
7
- warning: { name: "amber", classes: "bg-warning-soft text-warning-soft-foreground" },
8
- danger: { name: "red", classes: "bg-destructive-soft text-destructive-soft-foreground" },
9
- info: { name: "blue", classes: "bg-info-soft text-info-soft-foreground" },
10
- neutral: { name: "gray", classes: "bg-accent text-muted-foreground" },
6
+ success: {
7
+ name: "green",
8
+ subtle: "bg-success-soft text-success-soft-foreground",
9
+ solid: "bg-success text-success-foreground",
10
+ },
11
+ warning: {
12
+ name: "amber",
13
+ subtle: "bg-warning-soft text-warning-soft-foreground",
14
+ solid: "bg-warning text-warning-foreground",
15
+ },
16
+ danger: {
17
+ name: "red",
18
+ subtle: "bg-destructive-soft text-destructive-soft-foreground",
19
+ solid: "bg-destructive text-destructive-foreground",
20
+ },
21
+ info: {
22
+ name: "blue",
23
+ subtle: "bg-info-soft text-info-soft-foreground",
24
+ solid: "bg-info text-info-foreground",
25
+ },
26
+ neutral: {
27
+ name: "gray",
28
+ subtle: "bg-accent text-foreground",
29
+ solid: "bg-muted-foreground text-background",
30
+ },
11
31
  };
12
32
  // One mark per tone, always the same one: the tone said again as a shape, so a
13
33
  // status reads without colour. The info dot is filled and still.
@@ -18,24 +38,52 @@ const MARK_BY_TONE = {
18
38
  info: CircleDot,
19
39
  neutral: CirclePause,
20
40
  };
41
+ // Every mark is a circle, which has less air round it than a square glyph, so
42
+ // it sits closer to the pill's edge.
43
+ const CIRCLE_MARK_INSET = {
44
+ sm: "has-data-[icon=inline-start]:pl-1",
45
+ md: "has-data-[icon=inline-start]:pl-1.25",
46
+ lg: "has-data-[icon=inline-start]:pl-2",
47
+ };
21
48
  /**
22
49
  * A record's state: a mark and a word in one of five tones.
23
50
  *
24
51
  * @family Status
25
- * @when A record's state, when it sets the row apart: failed, waiting on a person, a step in
52
+ * @when "Use Badge for short, scannable metadata that sits next to the thing it describes: status, plan tier, environment, or role." (https://vercel.com/geist/badge)
53
+ * Ours: a record's state, when it sets the row apart: failed, waiting on a person, a step in
26
54
  * motion, paused, connected. Gray is every terminal state that needs no action.
27
- * @instead For a category (an installation, a partner) use `Tag`. For a control reporting its own
28
- * action use `ActionStatus`. For a mark beside a word that already names the state, `StatusDot`.
29
- * @behaviour Still: a status never moves and is never a button. Each app keeps one value-to-tone
30
- * map in one module; nothing else picks a status colour. A healthy record shows no badge.
31
- * @words A state, not a verb: *Failed*, *Waiting for you*. Sentence case, one to three words, no
55
+ * "Map meaning to color: `green` for healthy, `red` for error, `amber` for warning, `blue` for informational or production, `gray` for neutral." (https://vercel.com/geist/badge)
56
+ * Ours: success is green, danger red, warning amber, info blue, neutral gray, whatever the state's
57
+ * name, in our colour values. The tone and the word are required, and the type asks for both.
58
+ * @instead "For non-deployment statuses (Workflow runs, Queue messages, Sandbox, Cron jobs), use a `Badge` with the canonical state vocabulary instead of repurposing the dot." (https://vercel.com/geist/status-dot)
59
+ * Ours: that `Badge` is `StatusBadge`. For a category (an installation, a partner) use `Tag`. For
60
+ * plain metadata (a role, a plan) use `Badge`. For a control reporting its own action use
61
+ * `ActionStatus`. For a mark beside a word that already names the state, `StatusDot`.
62
+ * @behaviour "Badges are static labels." (https://vercel.com/geist/badge)
63
+ * "Don’t wire `onClick` onto them; promote to a Button or link if the user can act on the value." (https://vercel.com/geist/badge)
64
+ * Ours: a status never moves and is never a button.
65
+ * "The `-subtle` suffix tones any of them down on dense surfaces." (https://vercel.com/geist/badge)
66
+ * Ours: `subtle`, the default, is for rows, tables, lists and menus: it fills the pill with the
67
+ * tone's soft ground and sets the mark and the word in its strong shade; gray takes the foreground
68
+ * colour, never a muted one. `solid` is for a status that stands on its own, such as an object's
69
+ * page header or a card title: it fills the pill with the tone's strong colour and sets the mark
70
+ * and the word on it. No border and no ring either way.
71
+ * "Don’t add a checkmark icon for success states or an X for errors; the variant carries that signal." (https://vercel.com/geist/badge)
72
+ * Ours: it always draws its tone's mark, even for success and error: the mark repeats the tone as a
73
+ * shape so a status reads without colour. Each app keeps one value-to-tone map in one module;
74
+ * nothing else picks a status colour. A healthy record shows no badge.
75
+ * @words "Title Case, one word when possible, two max: `Active`, `Pending`, `Pro`, `Enterprise Trial`." (https://vercel.com/geist/badge)
76
+ * Ours: a state, not a verb (*Failed*, *Waiting for you*), in sentence case, one to three words, no
32
77
  * trailing ellipsis. Italian runs a third longer: *In attesa di te*.
33
- * @access The word is the name; the mark is `aria-hidden` and repeats the tone as a shape, so
34
- * colour never carries the state alone. Not focusable.
78
+ * "Match the canonical API or log term: `Production` not `Prod`, `Deployed` not `Live`, `Canceled` not `Cancelled` (the Vercel API uses one L)." (https://vercel.com/geist/badge)
79
+ * "Skip stuffing sentences inside (`Currently Active`, `You are on Pro`); the surrounding row supplies the context." (https://vercel.com/geist/badge)
80
+ * @access "Don’t rely on color alone; the text has to be readable without it." (https://vercel.com/geist/badge)
81
+ * Ours: the word is the name; the mark is `aria-hidden`, so colour never carries the state alone.
82
+ * Not focusable.
35
83
  */
36
- function StatusBadge({ tone, label, since, className, ...props }) {
84
+ function StatusBadge({ tone, label, since, className, size = "md", emphasis = "subtle", ...props }) {
37
85
  const Mark = MARK_BY_TONE[tone];
38
86
  const fill = FILL_BY_TONE[tone];
39
- return (_jsxs(Badge, { className: cn(fill.classes, "has-data-[icon=inline-start]:pl-2", className), "data-variant": fill.name, ...props, children: [_jsx(Mark, { "aria-hidden": "true", "data-icon": "inline-start" }), label, since ? (_jsx("span", { className: "tabular-nums", "data-slot": "status-badge-since", children: since })) : null] }));
87
+ return (_jsxs(Badge, { className: cn(fill[emphasis], CIRCLE_MARK_INSET[size], className), "data-emphasis": emphasis, "data-variant": fill.name, icon: _jsx(Mark, { "aria-hidden": "true" }), size: size, ...props, children: [label, since ? (_jsx("span", { className: "tabular-nums", "data-slot": "status-badge-since", children: since })) : null] }));
40
88
  }
41
89
  export { StatusBadge };