@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,32 +1,54 @@
1
1
  "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { Tabs as TabsPrimitive } from "@base-ui/react/tabs";
5
5
  import { mergeProps } from "@base-ui/react/merge-props";
6
6
  import { useRender } from "@base-ui/react/use-render";
7
7
  import { cva } from "class-variance-authority";
8
+ import { Tooltip, TooltipContent, TooltipTrigger } from "./tooltip.js";
8
9
  import { cn } from "../lib/utils.js";
9
10
  /**
10
11
  * Panels of one surface that switch in place.
11
12
  *
12
13
  * @family Navigation
13
- * @when Sibling views of one object that switch in place inside one surface.
14
- * @instead Views with their own URL are `TabsNav`. A choice that changes a value is a `RadioGroup`
15
- * or `ToggleGroup`. A stable destination belongs in the `Sidebar`. A tab never opens a new scope.
16
- * @behaviour One treatment among siblings, chosen through `variant`, never a page border. Arrow
17
- * keys move, one tab stop. The underline fades on `confirm`, 180 ms.
18
- * @words Nouns, one or two words: *Overview*, *Installations*. Italian (*Installazioni*) scrolls,
19
- * never wraps or truncates.
20
- * @access `tablist`, `tab`, `tabpanel` with `aria-selected`.
14
+ * @when "Use Tabs to switch between sibling views inside a single page (`Overview`, `Logs`, `Settings`)." (https://vercel.com/geist/tabs)
15
+ * "Cap a Tabs row at 5–7 entries on desktop and 3–4 on mobile. Past that, consolidate or move secondary views behind a `Menu`." (https://vercel.com/geist/tabs)
16
+ * Ours: the cap is 7 on a desktop and 4 on a phone.
17
+ * @instead "For navigation between unrelated pages, use a sub-menu, not Tabs." (https://vercel.com/geist/tabs) "Tabs imply the views share scope, URL parent, and data model." (https://vercel.com/geist/tabs)
18
+ * Ours: views with their own URL are `TabsNav`. A choice that changes a value is a `RadioGroup` or
19
+ * `ToggleGroup`. A stable destination belongs in the `Sidebar`.
20
+ * @behaviour "Selecting a tab is instant; don’t trigger network confirmation or toast on tab change." (https://vercel.com/geist/tabs)
21
+ * "Reflect the active tab in the URL (query param or path) so deep-links and refresh restore state." (https://vercel.com/geist/tabs)
22
+ * "Disable individual tabs only for permission or empty-state reasons; pair the disabled tab with a `tooltip` that names the constraint." (https://vercel.com/geist/tabs)
23
+ * Ours: the `tooltip` is `disabledReason`, shown on hover and focus and kept as the tab's
24
+ * description. One treatment among siblings, chosen through `variant`, never a page border: `line`
25
+ * (50 px, a 2 px ink underline over the row's 1 px rule) for a page's collections, `default` (a
26
+ * 32 px pill on the selection fill) for an object's sections. The page owns the chosen tab: `value`
27
+ * and `onValueChange` are required. There is no sliding underline. Colour is neutral only: the
28
+ * chosen tab is ink, the rest are muted until hover, and a disabled tab is never dimmed: in `line`
29
+ * it reads as an unchosen one, in `default` it sits on the selection fill with muted text, both
30
+ * with a not-allowed cursor.
31
+ * @words "`tabs[].title` is Title Case, 1–2 words, and names the destination noun (`Overview`, `Logs`, `Settings`). Verbs belong on buttons; `View Logs` is wrong on a tab." (https://vercel.com/geist/tabs)
32
+ * "`tabs[].tooltip` is sentence case and explains the constraint (`Only visible to project owners.`), not the tab’s purpose." (https://vercel.com/geist/tabs)
33
+ * "Don’t append a count to the title (`Logs (12)`); use a badge slot instead and drop the badge at zero." (https://vercel.com/geist/tabs)
34
+ * Ours: the title is sentence case (*Overview*, *Installations*), not Title Case. There is no badge
35
+ * slot: a count belongs to the list's footer. A reason is *Only owners see billing*. Italian
36
+ * (*Installazioni*) scrolls, never wraps or truncates.
37
+ * @access "Keep Left/Right arrows moving focus across tabs and Enter/Space activating; don’t hijack with global shortcuts." (https://vercel.com/geist/tabs)
38
+ * "Label the tablist with `aria-label` when no visible heading sits above it (`aria-label="Sections"`)." (https://vercel.com/geist/tabs)
39
+ * "Maintain a visible focus ring on the active tab; don’t suppress focus styles for visual polish." (https://vercel.com/geist/tabs)
40
+ * Ours: the arrow keys move with one tab stop. `tablist`, `tab`, `tabpanel` with `aria-selected`.
41
+ * The row is named by `aria-label` or `aria-labelledby`, which the type requires; a disabled tab is
42
+ * `aria-disabled`.
21
43
  */
22
44
  function Tabs({ className, orientation = "horizontal", ...props }) {
23
45
  return (_jsx(TabsPrimitive.Root, { "data-slot": "tabs", "data-orientation": orientation, orientation: orientation, className: cn("group/tabs flex min-w-0 gap-4 data-horizontal:flex-col", className), ...props }));
24
46
  }
25
- const tabsListVariants = cva("group/tabs-list inline-flex max-w-full w-fit items-center justify-start gap-1 overflow-x-auto text-placeholder group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col", {
47
+ const tabsListVariants = cva("group/tabs-list inline-flex max-w-full w-fit items-center justify-start gap-0 overflow-x-auto text-muted-foreground group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col", {
26
48
  variants: {
27
49
  variant: {
28
50
  default: "",
29
- line: "rounded-none bg-transparent",
51
+ line: "rounded-none bg-transparent group-data-horizontal/tabs:w-full group-data-horizontal/tabs:gap-6 group-data-horizontal/tabs:pb-px group-data-horizontal/tabs:shadow-[inset_0_-1px_0_0_var(--border)]",
30
52
  },
31
53
  },
32
54
  defaultVariants: {
@@ -36,13 +58,31 @@ const tabsListVariants = cva("group/tabs-list inline-flex max-w-full w-fit items
36
58
  function TabsList({ className, variant = "default", ...props }) {
37
59
  return (_jsx(TabsPrimitive.List, { "data-slot": "tabs-list", "data-variant": variant, className: cn(tabsListVariants({ variant }), className), ...props }));
38
60
  }
39
- const tabShape = "nc-transition-paint relative inline-flex shrink-0 h-control-height min-h-touch-target min-w-touch-target items-center justify-center gap-1.5 rounded-sm px-3 text-sm font-medium whitespace-nowrap text-placeholder hover:text-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4";
40
- function TabsTrigger({ className, ...props }) {
41
- return (_jsx(TabsPrimitive.Tab, { "data-slot": "tabs-trigger", className: cn(tabShape, "group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start", "group-data-[variant=default]/tabs-list:data-active:bg-selection group-data-[variant=default]/tabs-list:data-active:text-selection-foreground", "group-data-[variant=line]/tabs-list:data-active:text-foreground", "after:absolute after:bg-foreground after:opacity-0 after:transition-opacity after:duration-[var(--nc-duration-confirm)] after:ease-[var(--nc-ease-out-strong)] group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-0 group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:right-0 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100", className), ...props }));
61
+ const tabShape = "nc-transition-paint relative inline-flex shrink-0 h-nadicode-control-height-sm min-h-touch-target min-w-touch-target items-center justify-center gap-1.5 rounded-sm px-3 text-label-sm font-normal whitespace-nowrap text-muted-foreground not-aria-disabled:hover:text-foreground aria-disabled:cursor-not-allowed focus-visible:-outline-offset-2 [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 group-data-[variant=line]/tabs-list:rounded-none group-data-[variant=line]/tabs-list:text-body-sm";
62
+ function TabsTrigger({ className, disabled, disabledReason, "aria-describedby": describedBy, ...props }) {
63
+ const reasonId = React.useId();
64
+ const description = [describedBy, disabledReason === undefined ? undefined : reasonId].filter(Boolean).join(" ") ||
65
+ undefined;
66
+ const tab = (_jsx(TabsPrimitive.Tab, { "data-slot": "tabs-trigger", disabled: disabled, "aria-describedby": description, className: cn(tabShape, "group-data-horizontal/tabs:group-data-[variant=line]/tabs-list:-mb-px group-data-horizontal/tabs:group-data-[variant=line]/tabs-list:h-12.5 group-data-horizontal/tabs:group-data-[variant=line]/tabs-list:px-0.5", "group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start", "group-data-[variant=default]/tabs-list:aria-disabled:bg-selection group-data-[variant=default]/tabs-list:data-active:bg-selection group-data-[variant=default]/tabs-list:data-active:text-selection-foreground", "group-data-[variant=line]/tabs-list:data-active:text-foreground", "after:absolute after:bg-foreground after:opacity-0 group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-0 group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:right-0 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100", className), ...props }));
67
+ if (disabledReason === undefined)
68
+ return tab;
69
+ return (_jsxs(_Fragment, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { render: tab }), _jsx(TooltipContent, { children: disabledReason })] }), _jsx("span", { hidden: true, id: reasonId, children: disabledReason })] }));
42
70
  }
43
71
  function TabsContent({ className, ...props }) {
44
72
  return (_jsx(TabsPrimitive.Panel, { "data-slot": "tabs-content", className: cn("min-w-0 flex-1 text-sm outline-none", className), ...props }));
45
73
  }
74
+ /** Which ends of a scrolled row hide links, so the row fades there to say more stand beyond. */
75
+ function hiddenTabs(element) {
76
+ const start = element.scrollLeft > 1;
77
+ const end = element.scrollLeft + element.clientWidth < element.scrollWidth - 1;
78
+ return start && end ? "both" : start ? "start" : end ? "end" : "none";
79
+ }
80
+ const HIDDEN_FADE = {
81
+ none: undefined,
82
+ start: "[mask-image:linear-gradient(to_right,transparent,black_2rem)]",
83
+ end: "[mask-image:linear-gradient(to_left,transparent,black_2rem)]",
84
+ both: "[mask-image:linear-gradient(to_right,transparent,black_2rem,black_calc(100%_-_2rem),transparent)]",
85
+ };
46
86
  /**
47
87
  * Sibling views of one object, each with its own URL, under the top bar.
48
88
  *
@@ -51,15 +91,43 @@ function TabsContent({ className, ...props }) {
51
91
  * sections), with `TabsLink` for each.
52
92
  * @instead Panels that switch in place are `Tabs`. A stable destination belongs in the `Sidebar`.
53
93
  * An object's ancestry is the `Breadcrumb`.
54
- * @behaviour Overflow scrolls sideways and brings the current link into view. The current link
55
- * takes the underline.
56
- * @words Nouns, one or two words: *Overview*, *Installations*. Italian scrolls, never wraps or
57
- * truncates.
58
- * @access A labelled `nav` of links with `aria-current="page"` on the current one.
94
+ * @behaviour "Reflect the active tab in the URL (query param or path) so deep-links and refresh restore state." (https://vercel.com/geist/tabs)
95
+ * Ours: each view is its own URL, so a link carries it. Overflow scrolls sideways and brings the
96
+ * current link into view, and the row fades out over 32 px at each end where links stand beyond it. The current link takes the selection fill, or in `line` an ink underline
97
+ * over the row's 1 px rule; the other links are muted until hover, with no hue. Sizes and spacing
98
+ * follow `Tabs`. The sub-pages of one object stand as the filled-pill row in a `band` under the top
99
+ * bar, as Vercel draws a deployment's tabs: the band is this component's, with `above` for the
100
+ * object's identity, so no page draws the border, the fill or the gutters around the row. The band
101
+ * keeps the page's own column and gutter, and the first link's words start at the page title's edge,
102
+ * its fill reaching into the gutter as Vercel's tabs do. The
103
+ * `line` row has its own rule and takes no band.
104
+ * @words "`tabs[].title` is Title Case, 1–2 words, and names the destination noun (`Overview`, `Logs`, `Settings`). Verbs belong on buttons; `View Logs` is wrong on a tab." (https://vercel.com/geist/tabs)
105
+ * "Don’t append a count to the title (`Logs (12)`); use a badge slot instead and drop the badge at zero." (https://vercel.com/geist/tabs)
106
+ * Ours: the title is sentence case (*Overview*, *Installations*), not Title Case. There is no badge
107
+ * slot: a count belongs to the list's footer. Italian scrolls, never wraps or truncates.
108
+ * @access "Label the tablist with `aria-label` when no visible heading sits above it (`aria-label="Sections"`)." (https://vercel.com/geist/tabs)
109
+ * "Maintain a visible focus ring on the active tab; don’t suppress focus styles for visual polish." (https://vercel.com/geist/tabs)
110
+ * Ours: a `nav` of links named by `aria-label` or `aria-labelledby`, which the type requires, with
111
+ * `aria-current="page"` on the current one.
59
112
  */
60
- function TabsNav({ className, children, variant = "default", ...props }) {
113
+ function TabsNav({ className, children, variant = "default", band = false, above, ...props }) {
61
114
  const navigation = React.useRef(null);
62
115
  const current = React.useRef(null);
116
+ const [hidden, setHidden] = React.useState("none");
117
+ React.useEffect(() => {
118
+ const element = navigation.current;
119
+ if (!element || typeof ResizeObserver === "undefined")
120
+ return;
121
+ const measure = () => setHidden(hiddenTabs(element));
122
+ measure();
123
+ const observer = new ResizeObserver(measure);
124
+ observer.observe(element);
125
+ element.addEventListener("scroll", measure, { passive: true });
126
+ return () => {
127
+ observer.disconnect();
128
+ element.removeEventListener("scroll", measure);
129
+ };
130
+ }, []);
63
131
  React.useEffect(() => {
64
132
  const element = navigation.current;
65
133
  const link = element?.querySelector('[aria-current="page"]') ?? null;
@@ -70,7 +138,10 @@ function TabsNav({ className, children, variant = "default", ...props }) {
70
138
  link.scrollIntoView({ block: "nearest", inline: "nearest" });
71
139
  }
72
140
  });
73
- return (_jsx("nav", { ref: navigation, "data-slot": "tabs-nav", "data-variant": variant, className: cn("group/tabs-nav min-w-0 overflow-x-auto", variant === "line" && "border-b border-border", className), ...props, children: _jsx("ul", { className: "flex w-max min-w-full items-center gap-1", children: children }) }));
141
+ const row = (_jsx("nav", { ref: navigation, "data-slot": "tabs-nav", "data-variant": variant, className: cn("group/tabs-nav group/tabs-list min-w-0 overflow-x-auto", HIDDEN_FADE[hidden], variant === "line" && "pb-px shadow-[inset_0_-1px_0_0_var(--border)]", className), ...props, children: _jsx("ul", { className: "flex w-max min-w-full items-center gap-0 group-data-[variant=line]/tabs-nav:gap-6", children: children }) }));
142
+ if (!band)
143
+ return row;
144
+ return (_jsx("div", { "data-slot": "tabs-nav-band", className: "border-b bg-background", children: _jsxs("div", { className: "mx-auto w-full max-w-7xl px-6", children: [above, _jsx("div", { className: "-mx-3 py-2", children: row })] }) }));
74
145
  }
75
146
  function TabsLink({ current = false, className, render, ...props }) {
76
147
  const link = useRender({
@@ -78,7 +149,7 @@ function TabsLink({ current = false, className, render, ...props }) {
78
149
  render,
79
150
  props: mergeProps({
80
151
  "aria-current": current ? "page" : undefined,
81
- className: cn(tabShape, "group-data-[variant=default]/tabs-nav:aria-[current=page]:bg-selection group-data-[variant=default]/tabs-nav:aria-[current=page]:text-selection-foreground", "group-data-[variant=line]/tabs-nav:rounded-none group-data-[variant=line]/tabs-nav:aria-[current=page]:text-foreground", "after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:bg-foreground after:opacity-0 after:transition-opacity after:duration-[var(--nc-duration-confirm)] group-data-[variant=line]/tabs-nav:aria-[current=page]:after:opacity-100", className),
152
+ className: cn(tabShape, "group-data-[variant=line]/tabs-nav:-mb-px group-data-[variant=line]/tabs-nav:h-12.5 group-data-[variant=line]/tabs-nav:px-0.5", "group-data-[variant=default]/tabs-nav:aria-[current=page]:bg-selection group-data-[variant=default]/tabs-nav:aria-[current=page]:text-selection-foreground", "group-data-[variant=line]/tabs-nav:aria-[current=page]:text-foreground", "after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:bg-foreground after:opacity-0 group-data-[variant=line]/tabs-nav:aria-[current=page]:after:opacity-100", className),
82
153
  }, props),
83
154
  state: { slot: "tabs-link", current },
84
155
  });
@@ -10,7 +10,10 @@ import { type VariantProps } from "class-variance-authority";
10
10
  * `buttonVariants`. Going to a record from its row is the record's name in `RecordIdentity`.
11
11
  * @behaviour Classes only: the caller renders the real anchor or router link. `inline` thickens its
12
12
  * underline on hover; `plain` and `quiet` underline on hover. Paint changes ride the shared paint
13
- * transition.
13
+ * transition. Colour: only `inline` takes the link blue, as Vercel puts blue on links and nowhere
14
+ * else in running text; `plain` keeps the colour of the text around it, and `quiet` is muted and
15
+ * turns ink on hover, which is how a card footer's or a list note's *Learn more* reads. A link that
16
+ * leaves the product ends in the arrow icon after its text, which `quiet` sizes.
14
17
  * @words The link's text names where it goes: *Open Billing*, *Read the privacy notice*; never
15
18
  * *Click here* or a bare URL.
16
19
  * @access A real `a` with an `href`. A link that leaves the product says so in its text or carries
@@ -1 +1 @@
1
- {"version":3,"file":"text-link.d.ts","sourceRoot":"","sources":["../../src/components/text-link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,gBAAgB;;8EAYpB,CAAC;AAEH,KAAK,YAAY,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE/E,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"text-link.d.ts","sourceRoot":"","sources":["../../src/components/text-link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAElE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,QAAA,MAAM,gBAAgB;;8EAYpB,CAAC;AAEH,KAAK,YAAY,GAAG,WAAW,CAAC,YAAY,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAE/E,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,CAAC"}
@@ -10,7 +10,10 @@ import { cva } from "class-variance-authority";
10
10
  * `buttonVariants`. Going to a record from its row is the record's name in `RecordIdentity`.
11
11
  * @behaviour Classes only: the caller renders the real anchor or router link. `inline` thickens its
12
12
  * underline on hover; `plain` and `quiet` underline on hover. Paint changes ride the shared paint
13
- * transition.
13
+ * transition. Colour: only `inline` takes the link blue, as Vercel puts blue on links and nowhere
14
+ * else in running text; `plain` keeps the colour of the text around it, and `quiet` is muted and
15
+ * turns ink on hover, which is how a card footer's or a list note's *Learn more* reads. A link that
16
+ * leaves the product ends in the arrow icon after its text, which `quiet` sizes.
14
17
  * @words The link's text names where it goes: *Open Billing*, *Read the privacy notice*; never
15
18
  * *Click here* or a bare URL.
16
19
  * @access A real `a` with an `href`. A link that leaves the product says so in its text or carries
@@ -0,0 +1,30 @@
1
+ import { type CopyButtonProps } from "./copy-button.js";
2
+ type TextWithCopyButtonProps = {
3
+ value: string;
4
+ ellipsis?: boolean | undefined;
5
+ className?: string | undefined;
6
+ } & Pick<CopyButtonProps, "copyLabel" | "copiedLabel" | "copyFailedLabel">;
7
+ /**
8
+ * A short exact value with the button that copies it.
9
+ *
10
+ * @family Data
11
+ * @when A short value someone reads and pastes elsewhere: an identifier, a checksum, a slug, a
12
+ * server address.
13
+ * @instead Several lines are a `CodeBlock`; a command is a `Snippet`. A value that needs no copying
14
+ * is plain text. The button alone, beside text that is not the value, is `CopyButton`.
15
+ * @behaviour Shows the value in the body type, with a 24 px `CopyButton` whose 16 px mark sits 6 px
16
+ * after it. The value is slightly softer than the full text colour and the mark softer still;
17
+ * hovering either takes both to the full text colour, with no fill, border or shadow. Only the
18
+ * button copies: the value stays selectable, so a copy the clipboard refuses can be done by hand. A
19
+ * value too long for its row wraps at any character; `ellipsis` instead cuts it in the middle in
20
+ * one line (`MiddleTruncate`) and the whole value is still what copies. The result shows as the
21
+ * button's check mark, with no toast.
22
+ * @words `copyLabel` names what is copied (*Copy config digest*), never a bare *Copy*; `copiedLabel`
23
+ * says what was copied (*Config digest copied*); `copyFailedLabel` says it failed (*Couldn't copy*).
24
+ * All three are required.
25
+ * @access The value is text, read in full. The button is named by `copyLabel`; the result is read
26
+ * once from its status.
27
+ */
28
+ declare function TextWithCopyButton({ className, copiedLabel, copyFailedLabel, copyLabel, ellipsis, value, }: TextWithCopyButtonProps): import("react").JSX.Element;
29
+ export { TextWithCopyButton, type TextWithCopyButtonProps };
30
+ //# sourceMappingURL=text-with-copy-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-with-copy-button.d.ts","sourceRoot":"","sources":["../../src/components/text-with-copy-button.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAI5E,KAAK,uBAAuB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC,GAAG,IAAI,CAAC,eAAe,EAAE,WAAW,GAAG,aAAa,GAAG,iBAAiB,CAAC,CAAC;AAQ3E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,WAAW,EACX,eAAe,EACf,SAAS,EACT,QAAgB,EAChB,KAAK,GACN,EAAE,uBAAuB,+BAwBzB;AAED,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,CAAC"}
@@ -0,0 +1,32 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { CopyButton } from "./copy-button.js";
4
+ import { MiddleTruncate } from "./middle-truncate.js";
5
+ import { cn } from "../lib/utils.js";
6
+ const VALUE = "text-body-md text-foreground/80 nc-transition-paint group-hover/copy:text-foreground";
7
+ const BUTTON_WITHOUT_FILL = "[&_[data-slot=button]]:hover:bg-transparent [&_[data-slot=button]]:active:bg-transparent";
8
+ /**
9
+ * A short exact value with the button that copies it.
10
+ *
11
+ * @family Data
12
+ * @when A short value someone reads and pastes elsewhere: an identifier, a checksum, a slug, a
13
+ * server address.
14
+ * @instead Several lines are a `CodeBlock`; a command is a `Snippet`. A value that needs no copying
15
+ * is plain text. The button alone, beside text that is not the value, is `CopyButton`.
16
+ * @behaviour Shows the value in the body type, with a 24 px `CopyButton` whose 16 px mark sits 6 px
17
+ * after it. The value is slightly softer than the full text colour and the mark softer still;
18
+ * hovering either takes both to the full text colour, with no fill, border or shadow. Only the
19
+ * button copies: the value stays selectable, so a copy the clipboard refuses can be done by hand. A
20
+ * value too long for its row wraps at any character; `ellipsis` instead cuts it in the middle in
21
+ * one line (`MiddleTruncate`) and the whole value is still what copies. The result shows as the
22
+ * button's check mark, with no toast.
23
+ * @words `copyLabel` names what is copied (*Copy config digest*), never a bare *Copy*; `copiedLabel`
24
+ * says what was copied (*Config digest copied*); `copyFailedLabel` says it failed (*Couldn't copy*).
25
+ * All three are required.
26
+ * @access The value is text, read in full. The button is named by `copyLabel`; the result is read
27
+ * once from its status.
28
+ */
29
+ function TextWithCopyButton({ className, copiedLabel, copyFailedLabel, copyLabel, ellipsis = false, value, }) {
30
+ return (_jsxs("div", { "data-slot": "text-with-copy-button", className: cn("group/copy flex w-fit max-w-full min-w-0 items-center gap-0.5 text-muted-foreground nc-transition-paint hover:text-foreground", BUTTON_WITHOUT_FILL, className), children: [ellipsis ? (_jsx(MiddleTruncate, { value: value, className: VALUE })) : (_jsx("span", { className: cn("min-w-0 break-all", VALUE), children: value })), _jsx(CopyButton, { value: value, copyLabel: copyLabel, copiedLabel: copiedLabel, copyFailedLabel: copyFailedLabel, size: "icon-xs" })] }));
31
+ }
32
+ export { TextWithCopyButton };
@@ -1,18 +1,48 @@
1
1
  import * as React from "react";
2
+ import { type FieldName } from "../internal/field-frame.js";
3
+ import { type FieldSize } from "../internal/input-box.js";
4
+ type TextareaProps = Omit<React.ComponentProps<"textarea">, "size"> & {
5
+ size?: FieldSize;
6
+ /** One muted sentence under the box that says what to enter, read with the box. */
7
+ description?: string;
8
+ /** The message under the box, in the product's words; it also marks the box invalid. */
9
+ error?: string;
10
+ } & FieldName;
2
11
  /**
3
12
  * Several lines of free text that grow with their content.
4
13
  *
5
14
  * @family Inputs
6
- * @when Several lines of free text: an Agent's instructions, a description, notes.
7
- * @instead One line is `Input`. Code or a value to copy is `CodeBlock`, read-only.
8
- * @behaviour At least 64 px, then it grows with its content (`field-sizing: content`). The same
9
- * edge, focus, invalid and disabled as `Input`. Whitespace is kept exactly; nothing trims it. A
10
- * character count shows only when a real limit exists.
11
- * @words The label names the content (*Instructions*); the help says who reads it and when. The
12
- * placeholder is a short example, not a paragraph.
13
- * @access A visible label tied by `id`; help and error through `aria-describedby`. In a dialog, the
14
- * footer's Save stays reachable while the box grows.
15
+ * @when "Retrieve multi-line user input." (https://vercel.com/geist/textarea) "Pick `<Textarea>` for
16
+ * content that wraps to multiple lines (commit messages, descriptions, notes); use `Input` for a
17
+ * single value like a name or domain." (https://vercel.com/geist/textarea)
18
+ * @instead Ours: code or a value to copy is `CodeBlock`, read-only.
19
+ * @behaviour Same ring, halo, hover, disabled and error as `Input`; the red of an error sits on the
20
+ * ring, the halo and the message only, and holds while the box has focus. It grows with its content
21
+ * (`field-sizing: content`) from a roomy 100 px minimum with a 10 px by 12 px inset; `lg` takes
22
+ * larger type and the larger corner, `sm` is the default's size. Read-only keeps the plain fill: it
23
+ * does not look disabled. `label` and `error` draw the `Field` parts around the box, and a string
24
+ * `label` requires `id`, as on `Input`; a box with no name does not compile. "Set a generous
25
+ * default `rows` and grow only when the surface has vertical room; don’t let the field push primary
26
+ * actions below the fold." (https://vercel.com/geist/textarea) Ours: there is no resize handle and
27
+ * `rows` does not set the height. Nothing caps the growth, so a form keeps its footer's primary
28
+ * action in view and lets the body scroll. "Validate on blur and pass a string to `error` to render
29
+ * the inline message; the validation replaces helper text on failure."
30
+ * (https://vercel.com/geist/textarea) "Trim leading and trailing whitespace on submit so empty
31
+ * newlines don’t pass a `required` check." (https://vercel.com/geist/textarea) Ours: typing keeps
32
+ * every space and newline; the save of `FormDialog`, `FormDrawer`, `RowEditForm` and
33
+ * `SettingsSection` trims the ends (see `Field`). A character count shows only when a real limit
34
+ * exists.
35
+ * @words "Labels are short Title Case nouns (`Description`, `Release Notes`); placeholders show an
36
+ * example value, not instructions like `Enter a description`." (https://vercel.com/geist/textarea)
37
+ * "Validation names the field and constraint, ends in a period, and skips `please` (`Description is
38
+ * required.`, `Release notes can’t exceed 500 characters.`)." (https://vercel.com/geist/textarea)
39
+ * "Render helper text as a sibling `<p>` linked through `aria-describedby`; sentence case, one
40
+ * sentence, with a period." (https://vercel.com/geist/textarea) Ours: the label names the content
41
+ * (*Instructions*) in sentence case. Help is the one-line description of the card or form around
42
+ * the box, not a `<p>` under it. The placeholder is a short example, not a paragraph.
43
+ * @access A visible label tied by `id`, or `aria-label`; the error through `aria-describedby`. In a
44
+ * dialog, the footer's Save stays reachable while the box grows.
15
45
  */
16
- declare function Textarea({ className, ...props }: React.ComponentProps<"textarea">): React.JSX.Element;
46
+ declare function Textarea({ label, description, error, size, className, ...props }: TextareaProps): React.JSX.Element;
17
47
  export { Textarea };
18
48
  //# sourceMappingURL=textarea.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../src/components/textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;GAaG;AACH,iBAAS,QAAQ,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,qBAW1E;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"textarea.d.ts","sourceRoot":"","sources":["../../src/components/textarea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAyC,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAqB7F,KAAK,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,GAAG;IACpE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,SAAS,CAAC;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,iBAAS,QAAQ,CAAC,EAChB,KAAK,EACL,WAAW,EACX,KAAK,EACL,IAAgB,EAChB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,aAAa,qBAef;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -1,20 +1,59 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cva } from "class-variance-authority";
2
3
  import { cn } from "../lib/utils.js";
4
+ import { FieldFrame } from "../internal/field-frame.js";
5
+ import { fieldDisabled, fieldRing, fieldStates } from "../internal/input-box.js";
6
+ const textareaVariants = cva([
7
+ "flex field-sizing-content min-h-25 w-full resize-none bg-(--nc-field,var(--background)) px-control-padding-inline py-2.5 placeholder:text-placeholder",
8
+ fieldRing,
9
+ fieldStates,
10
+ fieldDisabled,
11
+ ], {
12
+ variants: {
13
+ size: {
14
+ sm: "rounded-sm text-base md:text-sm",
15
+ default: "rounded-sm text-base md:text-sm",
16
+ lg: "rounded-md text-base",
17
+ },
18
+ },
19
+ defaultVariants: { size: "default" },
20
+ });
3
21
  /**
4
22
  * Several lines of free text that grow with their content.
5
23
  *
6
24
  * @family Inputs
7
- * @when Several lines of free text: an Agent's instructions, a description, notes.
8
- * @instead One line is `Input`. Code or a value to copy is `CodeBlock`, read-only.
9
- * @behaviour At least 64 px, then it grows with its content (`field-sizing: content`). The same
10
- * edge, focus, invalid and disabled as `Input`. Whitespace is kept exactly; nothing trims it. A
11
- * character count shows only when a real limit exists.
12
- * @words The label names the content (*Instructions*); the help says who reads it and when. The
13
- * placeholder is a short example, not a paragraph.
14
- * @access A visible label tied by `id`; help and error through `aria-describedby`. In a dialog, the
15
- * footer's Save stays reachable while the box grows.
25
+ * @when "Retrieve multi-line user input." (https://vercel.com/geist/textarea) "Pick `<Textarea>` for
26
+ * content that wraps to multiple lines (commit messages, descriptions, notes); use `Input` for a
27
+ * single value like a name or domain." (https://vercel.com/geist/textarea)
28
+ * @instead Ours: code or a value to copy is `CodeBlock`, read-only.
29
+ * @behaviour Same ring, halo, hover, disabled and error as `Input`; the red of an error sits on the
30
+ * ring, the halo and the message only, and holds while the box has focus. It grows with its content
31
+ * (`field-sizing: content`) from a roomy 100 px minimum with a 10 px by 12 px inset; `lg` takes
32
+ * larger type and the larger corner, `sm` is the default's size. Read-only keeps the plain fill: it
33
+ * does not look disabled. `label` and `error` draw the `Field` parts around the box, and a string
34
+ * `label` requires `id`, as on `Input`; a box with no name does not compile. "Set a generous
35
+ * default `rows` and grow only when the surface has vertical room; don’t let the field push primary
36
+ * actions below the fold." (https://vercel.com/geist/textarea) Ours: there is no resize handle and
37
+ * `rows` does not set the height. Nothing caps the growth, so a form keeps its footer's primary
38
+ * action in view and lets the body scroll. "Validate on blur and pass a string to `error` to render
39
+ * the inline message; the validation replaces helper text on failure."
40
+ * (https://vercel.com/geist/textarea) "Trim leading and trailing whitespace on submit so empty
41
+ * newlines don’t pass a `required` check." (https://vercel.com/geist/textarea) Ours: typing keeps
42
+ * every space and newline; the save of `FormDialog`, `FormDrawer`, `RowEditForm` and
43
+ * `SettingsSection` trims the ends (see `Field`). A character count shows only when a real limit
44
+ * exists.
45
+ * @words "Labels are short Title Case nouns (`Description`, `Release Notes`); placeholders show an
46
+ * example value, not instructions like `Enter a description`." (https://vercel.com/geist/textarea)
47
+ * "Validation names the field and constraint, ends in a period, and skips `please` (`Description is
48
+ * required.`, `Release notes can’t exceed 500 characters.`)." (https://vercel.com/geist/textarea)
49
+ * "Render helper text as a sibling `<p>` linked through `aria-describedby`; sentence case, one
50
+ * sentence, with a period." (https://vercel.com/geist/textarea) Ours: the label names the content
51
+ * (*Instructions*) in sentence case. Help is the one-line description of the card or form around
52
+ * the box, not a `<p>` under it. The placeholder is a short example, not a paragraph.
53
+ * @access A visible label tied by `id`, or `aria-label`; the error through `aria-describedby`. In a
54
+ * dialog, the footer's Save stays reachable while the box grows.
16
55
  */
17
- function Textarea({ className, ...props }) {
18
- return (_jsx("textarea", { "data-slot": "textarea", className: cn("flex field-sizing-content min-h-16 w-full rounded-sm border border-input bg-background px-control-padding-inline py-2 text-base transition-colors placeholder:text-placeholder disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive md:text-sm", className), ...props }));
56
+ function Textarea({ label, description, error, size = "default", className, ...props }) {
57
+ return (_jsx(FieldFrame, { label: label, description: description, error: error, size: size, control: props, children: (aria) => (_jsx("textarea", { "data-slot": "textarea", "data-size": size, "data-field-frame": "", className: cn(textareaVariants({ size }), className), ...props, ...aria })) }));
19
58
  }
20
59
  export { Textarea };
@@ -10,7 +10,7 @@ export type ThemeModeOption = {
10
10
  mode: ThemeMode;
11
11
  selected: boolean;
12
12
  };
13
- export type ThemeModeSwitcherProps = Omit<React.ComponentProps<typeof RadioGroup>, "children" | "defaultValue" | "onValueChange" | "value"> & {
13
+ export type ThemeModeSwitcherProps = Omit<React.ComponentProps<typeof RadioGroup>, "aria-label" | "aria-labelledby" | "children" | "defaultValue" | "onValueChange" | "value"> & {
14
14
  "aria-label": string;
15
15
  compact?: boolean;
16
16
  itemClassName?: string;
@@ -49,4 +49,21 @@ export declare function ThemeModeMenu({ label, labels, value, onValueChange, dis
49
49
  onValueChange: (value: ThemeMode) => void;
50
50
  disabled?: boolean;
51
51
  }): React.JSX.Element;
52
+ /**
53
+ * The appearance as one small pill of three icons, for the corner of a page.
54
+ *
55
+ * @family Choices
56
+ * @when The appearance outside a settings page, where it must take little room: the corner of a sign-in page or a site's footer.
57
+ * @instead On a settings page, where the choice has room for its names, it is ThemeModeSwitcher; inside a menu, ThemeModeMenu.
58
+ * @behaviour One control of three icon segments, System, Light and Dark, the chosen one filled; choosing applies at once. Each segment shows its name as a tooltip.
59
+ * @words Each segment's name from the product's catalogue: "System", "Light", "Dark"; the control's name is the setting's: "Theme".
60
+ * @access A radio group named by `aria-label`; each segment is a radio named by its label, moved through with the arrow keys.
61
+ */
62
+ export declare function ThemeModeSegments({ "aria-label": ariaLabel, disabled, labels, onValueChange, value, }: {
63
+ "aria-label": string;
64
+ disabled?: boolean;
65
+ labels: ThemeModeOptionLabels;
66
+ onValueChange: (value: ThemeMode) => void;
67
+ value: ThemeMode;
68
+ }): React.JSX.Element;
52
69
  //# sourceMappingURL=theme-mode-switcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme-mode-switcher.d.ts","sourceRoot":"","sources":["../../src/components/theme-mode-switcher.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,UAAU,EAAkB,MAAM,0BAA0B,CAAC;AAEtE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAE9D,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EACvC,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,OAAO,CACxD,GAAG;IACF,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1D,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAQF;;;;;;;;;GASG;AACH,iBAAS,iBAAiB,CAAC,EACzB,YAAY,EAAE,SAAS,EACvB,SAAS,EACT,OAAe,EACf,QAAQ,EACR,aAAa,EACb,MAAM,EACN,aAAa,EACb,UAAU,EACV,KAAK,EACL,GAAG,KAAK,EACT,EAAE,sBAAsB,qBA6CxB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,MAAM,EACN,KAAK,EACL,aAAa,EACb,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,qBAAqB,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,qBAkBA"}
1
+ {"version":3,"file":"theme-mode-switcher.d.ts","sourceRoot":"","sources":["../../src/components/theme-mode-switcher.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,EAAE,UAAU,EAAkB,MAAM,0BAA0B,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG3E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAE9D,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACvC,KAAK,CAAC,cAAc,CAAC,OAAO,UAAU,CAAC,EACvC,YAAY,GAAG,iBAAiB,GAAG,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,OAAO,CAC3F,GAAG;IACF,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,KAAK,CAAC,SAAS,CAAC;IAC1D,KAAK,EAAE,SAAS,CAAC;CAClB,CAAC;AAQF;;;;;;;;;GASG;AACH,iBAAS,iBAAiB,CAAC,EACzB,YAAY,EAAE,SAAS,EACvB,SAAS,EACT,OAAe,EACf,QAAQ,EACR,aAAa,EACb,MAAM,EACN,aAAa,EACb,UAAU,EACV,KAAK,EACL,GAAG,KAAK,EACT,EAAE,sBAAsB,qBA6CxB;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC;AAE7B;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,MAAM,EACN,KAAK,EACL,aAAa,EACb,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,qBAAqB,CAAC;IAC9B,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,qBAkBA;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,YAAY,EAAE,SAAS,EACvB,QAAQ,EACR,MAAM,EACN,aAAa,EACb,KAAK,GACN,EAAE;IACD,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,qBAAqB,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IAC1C,KAAK,EAAE,SAAS,CAAC;CAClB,qBAeA"}
@@ -3,6 +3,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
3
3
  import { MonitorIcon, MoonIcon, SunIcon } from "lucide-react";
4
4
  import { MenuChoiceRow } from "./menu-choice-row.js";
5
5
  import { RadioGroup, RadioGroupItem } from "./radio-group.js";
6
+ import { SegmentedControl } from "./segmented-control.js";
6
7
  import { toggleVariants } from "./toggle.js";
7
8
  import { isThemeMode, themeModes } from "../lib/theme-mode.js";
8
9
  import { cn } from "../lib/utils.js";
@@ -23,7 +24,7 @@ const themeModeIcons = {
23
24
  * @access A radio group named by `aria-label`; each mode is a radio with its name, moved through with the arrow keys.
24
25
  */
25
26
  function ThemeModeSwitcher({ "aria-label": ariaLabel, className, compact = false, disabled, itemClassName, labels, onValueChange, renderItem, value, ...props }) {
26
- return (_jsx(RadioGroup, { "aria-label": ariaLabel, className: cn("max-w-full grid-cols-3", className), disabled: disabled, onValueChange: (nextMode) => {
27
+ return (_jsx(RadioGroup, { "aria-label": ariaLabel, className: cn("@container/theme-mode max-w-full grid-cols-3 gap-2", className), disabled: disabled, onValueChange: (nextMode) => {
27
28
  if (isThemeMode(nextMode)) {
28
29
  onValueChange(nextMode);
29
30
  }
@@ -31,7 +32,7 @@ function ThemeModeSwitcher({ "aria-label": ariaLabel, className, compact = false
31
32
  const Icon = themeModeIcons[mode];
32
33
  const label = labels[mode];
33
34
  const selected = value === mode;
34
- return (_jsx(RadioGroupItem, { "aria-label": label, className: cn(toggleVariants({ variant: "outline" }), "aspect-auto w-auto min-w-0 gap-1.5 data-checked:border-transparent data-checked:bg-selection data-checked:text-selection-foreground", compact && "text-xs", itemClassName), disabled: disabled, value: mode, children: renderItem ? (renderItem({ Icon, label, mode, selected })) : (_jsxs(_Fragment, { children: [_jsx(Icon, { "aria-hidden": "true", "data-icon": true }), _jsx("span", { className: "min-w-0 truncate", children: label })] })) }, mode));
35
+ return (_jsx(RadioGroupItem, { "aria-label": label, className: cn(toggleVariants({ variant: "outline" }), "aspect-auto w-auto min-w-0 gap-1.5 @max-[24rem]/theme-mode:px-2 data-checked:border-transparent data-checked:bg-selection data-checked:text-selection-foreground", compact && "text-xs", itemClassName), disabled: disabled, value: mode, children: renderItem ? (renderItem({ Icon, label, mode, selected })) : (_jsxs(_Fragment, { children: [_jsx(Icon, { "aria-hidden": "true", "data-icon": true }), _jsx("span", { className: "min-w-0", children: label })] })) }, mode));
35
36
  }) }));
36
37
  }
37
38
  export { ThemeModeSwitcher };
@@ -56,3 +57,20 @@ export function ThemeModeMenu({ label, labels, value, onValueChange, disabled, }
56
57
  };
57
58
  }) }));
58
59
  }
60
+ /**
61
+ * The appearance as one small pill of three icons, for the corner of a page.
62
+ *
63
+ * @family Choices
64
+ * @when The appearance outside a settings page, where it must take little room: the corner of a sign-in page or a site's footer.
65
+ * @instead On a settings page, where the choice has room for its names, it is ThemeModeSwitcher; inside a menu, ThemeModeMenu.
66
+ * @behaviour One control of three icon segments, System, Light and Dark, the chosen one filled; choosing applies at once. Each segment shows its name as a tooltip.
67
+ * @words Each segment's name from the product's catalogue: "System", "Light", "Dark"; the control's name is the setting's: "Theme".
68
+ * @access A radio group named by `aria-label`; each segment is a radio named by its label, moved through with the arrow keys.
69
+ */
70
+ export function ThemeModeSegments({ "aria-label": ariaLabel, disabled, labels, onValueChange, value, }) {
71
+ return (_jsx(SegmentedControl, { "aria-label": ariaLabel, disabled: disabled, onValueChange: onValueChange, options: [
72
+ { value: "system", label: labels.system, icon: _jsx(MonitorIcon, {}), iconOnly: true },
73
+ { value: "light", label: labels.light, icon: _jsx(SunIcon, {}), iconOnly: true },
74
+ { value: "dark", label: labels.dark, icon: _jsx(MoonIcon, {}), iconOnly: true },
75
+ ], size: "sm", value: value }));
76
+ }
@@ -3,23 +3,43 @@ import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
3
3
  import { ToggleGroup as ToggleGroupPrimitive } from "@base-ui/react/toggle-group";
4
4
  import { type VariantProps } from "class-variance-authority";
5
5
  import { toggleVariants } from "./toggle.js";
6
+ type ToggleGroupName = {
7
+ "aria-label": string;
8
+ "aria-labelledby"?: undefined;
9
+ } | {
10
+ "aria-labelledby": string;
11
+ "aria-label"?: undefined;
12
+ };
13
+ type ToggleGroupMemberName = {
14
+ children: string;
15
+ "aria-label"?: string;
16
+ } | {
17
+ "aria-label": string;
18
+ children?: React.ReactNode;
19
+ };
6
20
  /**
7
21
  * Pressed buttons that belong together.
8
22
  *
9
23
  * @family Choices
10
- * @when Pressed buttons that belong together: a list or grid view, which details a chat shows.
11
- * @instead A segmented control that sets a value, such as the theme or a period, is a `RadioGroup`
12
- * drawn with the toggle classes, as `ThemeModeSwitcher` does. Panels of one object are `Tabs`.
24
+ * @when Pressed buttons that belong together: which details a chat shows, the marks on a toolbar.
25
+ * @instead A value that is always exactly one of two or three, such as a list or grid view, is a
26
+ * `SegmentedControl`: its options are radios, so pressing the chosen one never clears it. The
27
+ * theme is `ThemeModeSwitcher`. Panels of one object are `Tabs`.
13
28
  * @behaviour Spacing 0 joins the members into one outline with one seam; spacing 2 keeps them 8 px
14
- * apart. Single or multiple pressed. Arrow keys move between members; Space presses.
15
- * @words Text members are short words of equal weight. Icon members always carry a name: *List*,
16
- * *Grid*.
29
+ * apart. With `multiple`, members are pressed independently and any number may be pressed, none
30
+ * included. Without it, at most one is pressed and pressing it again clears it; a value that is
31
+ * always one of two or three is a `SegmentedControl`. The group is named with `aria-label`
32
+ * or `aria-labelledby`, and a member is either a word as its children or carries an `aria-label`;
33
+ * a group or an icon member without a name does not compile. Colour: a pressed member takes the
34
+ * accent grey and nothing takes a hue. Arrow keys move between members; Space presses.
35
+ * @words Text members are short words of equal weight. Icon members always carry a name: *Tools*,
36
+ * *Reasoning*.
17
37
  * @access `role="group"` with a name; each member a button with `aria-pressed`.
18
38
  */
19
- declare function ToggleGroup({ className, variant, size, spacing, orientation, style, children, ...props }: ToggleGroupPrimitive.Props & VariantProps<typeof toggleVariants> & {
39
+ declare function ToggleGroup({ className, variant, size, spacing, orientation, style, children, ...props }: Omit<ToggleGroupPrimitive.Props, "aria-label" | "aria-labelledby"> & ToggleGroupName & VariantProps<typeof toggleVariants> & {
20
40
  spacing?: number;
21
41
  orientation?: "horizontal" | "vertical";
22
42
  }): React.JSX.Element;
23
- declare function ToggleGroupItem({ className, children, variant, size, ...props }: TogglePrimitive.Props & VariantProps<typeof toggleVariants>): React.JSX.Element;
43
+ declare function ToggleGroupItem({ className, children, variant, size, ...props }: Omit<TogglePrimitive.Props, "children"> & ToggleGroupMemberName & VariantProps<typeof toggleVariants>): React.JSX.Element;
24
44
  export { ToggleGroup, ToggleGroupItem };
25
45
  //# sourceMappingURL=toggle-group.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"toggle-group.d.ts","sourceRoot":"","sources":["../../src/components/toggle-group.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAcrD;;;;;;;;;;;;GAYG;AACH,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAW,EACX,WAA0B,EAC1B,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,oBAAoB,CAAC,KAAK,GAC3B,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CACzC,qBA2BF;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,QAAQ,EACR,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,qBAsB7D;AAED,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"toggle-group.d.ts","sourceRoot":"","sources":["../../src/components/toggle-group.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAcrD,KAAK,eAAe,GAChB;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,SAAS,CAAA;CAAE,GACvD;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC;AAE5D,KAAK,qBAAqB,GACtB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAC;AAEzD;;;;;;;;;;;;;;;;;;GAkBG;AACH,iBAAS,WAAW,CAAC,EACnB,SAAS,EACT,OAAO,EACP,IAAI,EACJ,OAAW,EACX,WAA0B,EAC1B,KAAK,EACL,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,iBAAiB,CAAC,GACnE,eAAe,GACf,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;CACzC,qBA2BF;AAED,iBAAS,eAAe,CAAC,EACvB,SAAS,EACT,QAAQ,EACR,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,UAAU,CAAC,GACxC,qBAAqB,GACrB,YAAY,CAAC,OAAO,cAAc,CAAC,qBAsBpC;AAED,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC"}