@nadicodeai/ui 12.1.101 → 12.1.103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. package/dist/components/accordion.d.ts +38 -12
  2. package/dist/components/accordion.d.ts.map +1 -1
  3. package/dist/components/accordion.js +36 -15
  4. package/dist/components/account-menu.d.ts +18 -18
  5. package/dist/components/account-menu.d.ts.map +1 -1
  6. package/dist/components/account-menu.js +17 -13
  7. package/dist/components/action-menu.d.ts +20 -19
  8. package/dist/components/action-menu.d.ts.map +1 -1
  9. package/dist/components/action-menu.js +22 -15
  10. package/dist/components/action-status.d.ts +14 -10
  11. package/dist/components/action-status.d.ts.map +1 -1
  12. package/dist/components/action-status.js +14 -10
  13. package/dist/components/activity-calendar.d.ts +3 -1
  14. package/dist/components/activity-calendar.d.ts.map +1 -1
  15. package/dist/components/activity-calendar.js +16 -2
  16. package/dist/components/activity-feed.d.ts +2 -2
  17. package/dist/components/activity-feed.d.ts.map +1 -1
  18. package/dist/components/activity-feed.js +14 -5
  19. package/dist/components/agent-card.d.ts +11 -5
  20. package/dist/components/agent-card.d.ts.map +1 -1
  21. package/dist/components/agent-card.js +13 -7
  22. package/dist/components/agent-list-row.js +1 -1
  23. package/dist/components/agent-orb-appearance.d.ts +7 -1
  24. package/dist/components/agent-orb-appearance.d.ts.map +1 -1
  25. package/dist/components/agent-orb-appearance.js +26 -0
  26. package/dist/components/agent-profile.d.ts +8 -7
  27. package/dist/components/agent-profile.d.ts.map +1 -1
  28. package/dist/components/agent-profile.js +6 -6
  29. package/dist/components/alert-dialog.d.ts +25 -16
  30. package/dist/components/alert-dialog.d.ts.map +1 -1
  31. package/dist/components/alert-dialog.js +30 -18
  32. package/dist/components/alert.d.ts +1 -1
  33. package/dist/components/avatar.d.ts +83 -17
  34. package/dist/components/avatar.d.ts.map +1 -1
  35. package/dist/components/avatar.js +89 -23
  36. package/dist/components/badge.d.ts +59 -8
  37. package/dist/components/badge.d.ts.map +1 -1
  38. package/dist/components/badge.js +57 -14
  39. package/dist/components/breadcrumb.d.ts +18 -7
  40. package/dist/components/breadcrumb.d.ts.map +1 -1
  41. package/dist/components/breadcrumb.js +37 -13
  42. package/dist/components/button-group.d.ts +12 -15
  43. package/dist/components/button-group.d.ts.map +1 -1
  44. package/dist/components/button-group.js +13 -17
  45. package/dist/components/button.d.ts +126 -23
  46. package/dist/components/button.d.ts.map +1 -1
  47. package/dist/components/button.js +164 -39
  48. package/dist/components/calendar.d.ts +26 -15
  49. package/dist/components/calendar.d.ts.map +1 -1
  50. package/dist/components/calendar.js +60 -46
  51. package/dist/components/card-row.d.ts +13 -5
  52. package/dist/components/card-row.d.ts.map +1 -1
  53. package/dist/components/card-row.js +24 -10
  54. package/dist/components/card.d.ts +6 -12
  55. package/dist/components/card.d.ts.map +1 -1
  56. package/dist/components/card.js +11 -16
  57. package/dist/components/carousel.d.ts +3 -3
  58. package/dist/components/carousel.d.ts.map +1 -1
  59. package/dist/components/carousel.js +7 -7
  60. package/dist/components/catalog-drawer.d.ts +7 -7
  61. package/dist/components/catalog-drawer.d.ts.map +1 -1
  62. package/dist/components/catalog-drawer.js +6 -6
  63. package/dist/components/chart-area-stacked.d.ts +1 -1
  64. package/dist/components/chart-area-stacked.d.ts.map +1 -1
  65. package/dist/components/chart-area-stacked.js +4 -4
  66. package/dist/components/chart-axis.d.ts +14 -1
  67. package/dist/components/chart-axis.d.ts.map +1 -1
  68. package/dist/components/chart-axis.js +11 -1
  69. package/dist/components/chart-bar-horizontal.d.ts +2 -2
  70. package/dist/components/chart-bar-horizontal.d.ts.map +1 -1
  71. package/dist/components/chart-bar-horizontal.js +14 -5
  72. package/dist/components/chart-bar-multiple.d.ts +1 -1
  73. package/dist/components/chart-bar-multiple.d.ts.map +1 -1
  74. package/dist/components/chart-bar-multiple.js +3 -3
  75. package/dist/components/chart-bar-stacked.d.ts +1 -1
  76. package/dist/components/chart-bar-stacked.d.ts.map +1 -1
  77. package/dist/components/chart-bar-stacked.js +3 -3
  78. package/dist/components/chart-card.d.ts +17 -6
  79. package/dist/components/chart-card.d.ts.map +1 -1
  80. package/dist/components/chart-card.js +11 -4
  81. package/dist/components/chart-date-range-control.d.ts +18 -9
  82. package/dist/components/chart-date-range-control.d.ts.map +1 -1
  83. package/dist/components/chart-date-range-control.js +43 -47
  84. package/dist/components/chart-sparkline.d.ts +4 -3
  85. package/dist/components/chart-sparkline.d.ts.map +1 -1
  86. package/dist/components/chart-sparkline.js +6 -5
  87. package/dist/components/check-counts.d.ts +44 -0
  88. package/dist/components/check-counts.d.ts.map +1 -0
  89. package/dist/components/check-counts.js +51 -0
  90. package/dist/components/checkbox.d.ts +39 -11
  91. package/dist/components/checkbox.d.ts.map +1 -1
  92. package/dist/components/checkbox.js +38 -11
  93. package/dist/components/choicebox.d.ts +96 -0
  94. package/dist/components/choicebox.d.ts.map +1 -0
  95. package/dist/components/choicebox.js +113 -0
  96. package/dist/components/clearable-input.d.ts +57 -0
  97. package/dist/components/clearable-input.d.ts.map +1 -0
  98. package/dist/components/clearable-input.js +58 -0
  99. package/dist/components/code-block.d.ts +77 -17
  100. package/dist/components/code-block.d.ts.map +1 -1
  101. package/dist/components/code-block.js +85 -15
  102. package/dist/components/collapsible.d.ts +27 -10
  103. package/dist/components/collapsible.d.ts.map +1 -1
  104. package/dist/components/collapsible.js +24 -9
  105. package/dist/components/collection-filters.d.ts +3 -1
  106. package/dist/components/collection-filters.d.ts.map +1 -1
  107. package/dist/components/collection-filters.js +7 -9
  108. package/dist/components/collection-page.d.ts +31 -10
  109. package/dist/components/collection-page.d.ts.map +1 -1
  110. package/dist/components/collection-page.js +14 -13
  111. package/dist/components/collection-search.d.ts +32 -10
  112. package/dist/components/collection-search.d.ts.map +1 -1
  113. package/dist/components/collection-search.js +24 -13
  114. package/dist/components/collection-sort.d.ts.map +1 -1
  115. package/dist/components/collection-sort.js +2 -2
  116. package/dist/components/collection-toolbar.d.ts +5 -2
  117. package/dist/components/collection-toolbar.d.ts.map +1 -1
  118. package/dist/components/collection-toolbar.js +7 -4
  119. package/dist/components/combobox.d.ts +97 -22
  120. package/dist/components/combobox.d.ts.map +1 -1
  121. package/dist/components/combobox.js +80 -28
  122. package/dist/components/command.d.ts +34 -21
  123. package/dist/components/command.d.ts.map +1 -1
  124. package/dist/components/command.js +33 -25
  125. package/dist/components/confirm-dialog.d.ts +23 -6
  126. package/dist/components/confirm-dialog.d.ts.map +1 -1
  127. package/dist/components/confirm-dialog.js +32 -13
  128. package/dist/components/context-menu.d.ts +14 -10
  129. package/dist/components/context-menu.d.ts.map +1 -1
  130. package/dist/components/context-menu.js +17 -12
  131. package/dist/components/copy-button.d.ts +5 -2
  132. package/dist/components/copy-button.d.ts.map +1 -1
  133. package/dist/components/copy-button.js +16 -8
  134. package/dist/components/data-table.d.ts +120 -54
  135. package/dist/components/data-table.d.ts.map +1 -1
  136. package/dist/components/data-table.js +163 -92
  137. package/dist/components/desktop-shell.d.ts +4 -2
  138. package/dist/components/desktop-shell.d.ts.map +1 -1
  139. package/dist/components/desktop-shell.js +3 -3
  140. package/dist/components/dialog.d.ts +63 -24
  141. package/dist/components/dialog.d.ts.map +1 -1
  142. package/dist/components/dialog.js +52 -31
  143. package/dist/components/disclosure-row.d.ts +1 -2
  144. package/dist/components/disclosure-row.d.ts.map +1 -1
  145. package/dist/components/disclosure-row.js +1 -2
  146. package/dist/components/disclosure.d.ts +1 -1
  147. package/dist/components/disclosure.js +1 -1
  148. package/dist/components/drawer.d.ts +33 -12
  149. package/dist/components/drawer.d.ts.map +1 -1
  150. package/dist/components/drawer.js +47 -35
  151. package/dist/components/dropdown-menu.d.ts +59 -14
  152. package/dist/components/dropdown-menu.d.ts.map +1 -1
  153. package/dist/components/dropdown-menu.js +58 -26
  154. package/dist/components/empty-state.d.ts +35 -12
  155. package/dist/components/empty-state.d.ts.map +1 -1
  156. package/dist/components/empty-state.js +35 -17
  157. package/dist/components/entry-scene.d.ts +4 -4
  158. package/dist/components/entry-scene.d.ts.map +1 -1
  159. package/dist/components/entry-scene.js +2 -2
  160. package/dist/components/field.d.ts +44 -14
  161. package/dist/components/field.d.ts.map +1 -1
  162. package/dist/components/field.js +49 -20
  163. package/dist/components/file-diff.d.ts.map +1 -1
  164. package/dist/components/file-diff.js +3 -4
  165. package/dist/components/form-dialog.d.ts +7 -7
  166. package/dist/components/form-dialog.d.ts.map +1 -1
  167. package/dist/components/form-dialog.js +13 -11
  168. package/dist/components/form-drawer.d.ts +10 -7
  169. package/dist/components/form-drawer.d.ts.map +1 -1
  170. package/dist/components/form-drawer.js +11 -10
  171. package/dist/components/gauge.d.ts +64 -0
  172. package/dist/components/gauge.d.ts.map +1 -0
  173. package/dist/components/gauge.js +73 -0
  174. package/dist/components/hover-card.d.ts +72 -14
  175. package/dist/components/hover-card.d.ts.map +1 -1
  176. package/dist/components/hover-card.js +51 -17
  177. package/dist/components/identity-mark.d.ts +8 -1
  178. package/dist/components/identity-mark.d.ts.map +1 -1
  179. package/dist/components/identity-mark.js +31 -5
  180. package/dist/components/input-group.d.ts +44 -21
  181. package/dist/components/input-group.d.ts.map +1 -1
  182. package/dist/components/input-group.js +74 -27
  183. package/dist/components/input.d.ts +64 -12
  184. package/dist/components/input.d.ts.map +1 -1
  185. package/dist/components/input.js +51 -15
  186. package/dist/components/item.d.ts +37 -15
  187. package/dist/components/item.d.ts.map +1 -1
  188. package/dist/components/item.js +41 -22
  189. package/dist/components/kbd.d.ts +49 -13
  190. package/dist/components/kbd.d.ts.map +1 -1
  191. package/dist/components/kbd.js +115 -16
  192. package/dist/components/kpi-card.d.ts +12 -4
  193. package/dist/components/kpi-card.d.ts.map +1 -1
  194. package/dist/components/kpi-card.js +13 -4
  195. package/dist/components/label.d.ts +17 -10
  196. package/dist/components/label.d.ts.map +1 -1
  197. package/dist/components/label.js +18 -11
  198. package/dist/components/library-shelf.d.ts +6 -6
  199. package/dist/components/library-shelf.d.ts.map +1 -1
  200. package/dist/components/library-shelf.js +5 -5
  201. package/dist/components/load-more-button.d.ts +35 -0
  202. package/dist/components/load-more-button.d.ts.map +1 -0
  203. package/dist/components/load-more-button.js +26 -0
  204. package/dist/components/menu-choice-row.d.ts +6 -8
  205. package/dist/components/menu-choice-row.d.ts.map +1 -1
  206. package/dist/components/menu-choice-row.js +8 -8
  207. package/dist/components/message-notice.d.ts +8 -13
  208. package/dist/components/message-notice.d.ts.map +1 -1
  209. package/dist/components/message-notice.js +25 -22
  210. package/dist/components/middle-truncate.d.ts +33 -0
  211. package/dist/components/middle-truncate.d.ts.map +1 -0
  212. package/dist/components/middle-truncate.js +72 -0
  213. package/dist/components/multi-select.d.ts +94 -0
  214. package/dist/components/multi-select.d.ts.map +1 -0
  215. package/dist/components/multi-select.js +132 -0
  216. package/dist/components/native-select.d.ts +37 -13
  217. package/dist/components/native-select.d.ts.map +1 -1
  218. package/dist/components/native-select.js +27 -11
  219. package/dist/components/notice-banner.d.ts +17 -10
  220. package/dist/components/notice-banner.d.ts.map +1 -1
  221. package/dist/components/notice-banner.js +12 -11
  222. package/dist/components/numbered-steps.d.ts +10 -4
  223. package/dist/components/numbered-steps.d.ts.map +1 -1
  224. package/dist/components/numbered-steps.js +9 -7
  225. package/dist/components/object-page.d.ts +40 -14
  226. package/dist/components/object-page.d.ts.map +1 -1
  227. package/dist/components/object-page.js +12 -10
  228. package/dist/components/object-workspace.d.ts +29 -10
  229. package/dist/components/object-workspace.d.ts.map +1 -1
  230. package/dist/components/object-workspace.js +18 -8
  231. package/dist/components/overview-page.d.ts +2 -2
  232. package/dist/components/overview-page.d.ts.map +1 -1
  233. package/dist/components/overview-page.js +8 -7
  234. package/dist/components/page-actions.d.ts +28 -8
  235. package/dist/components/page-actions.d.ts.map +1 -1
  236. package/dist/components/page-actions.js +22 -25
  237. package/dist/components/page-header.d.ts +11 -4
  238. package/dist/components/page-header.d.ts.map +1 -1
  239. package/dist/components/page-header.js +10 -5
  240. package/dist/components/pending-label.d.ts +6 -5
  241. package/dist/components/pending-label.d.ts.map +1 -1
  242. package/dist/components/pending-label.js +14 -6
  243. package/dist/components/picture-label.d.ts +2 -2
  244. package/dist/components/picture-label.d.ts.map +1 -1
  245. package/dist/components/picture-label.js +3 -3
  246. package/dist/components/portal-sidebar-frame.d.ts +9 -21
  247. package/dist/components/portal-sidebar-frame.d.ts.map +1 -1
  248. package/dist/components/portal-sidebar-frame.js +13 -27
  249. package/dist/components/progress-checklist.d.ts +46 -0
  250. package/dist/components/progress-checklist.d.ts.map +1 -0
  251. package/dist/components/progress-checklist.js +46 -0
  252. package/dist/components/progress.d.ts +48 -8
  253. package/dist/components/progress.d.ts.map +1 -1
  254. package/dist/components/progress.js +92 -16
  255. package/dist/components/prose.d.ts +19 -0
  256. package/dist/components/prose.d.ts.map +1 -0
  257. package/dist/components/prose.js +29 -0
  258. package/dist/components/radio-group.d.ts +51 -12
  259. package/dist/components/radio-group.d.ts.map +1 -1
  260. package/dist/components/radio-group.js +42 -12
  261. package/dist/components/reading-column.js +1 -1
  262. package/dist/components/record-identity.d.ts +6 -5
  263. package/dist/components/record-identity.d.ts.map +1 -1
  264. package/dist/components/record-identity.js +12 -3
  265. package/dist/components/record-list.d.ts +117 -27
  266. package/dist/components/record-list.d.ts.map +1 -1
  267. package/dist/components/record-list.js +185 -55
  268. package/dist/components/record-time.d.ts +20 -7
  269. package/dist/components/record-time.d.ts.map +1 -1
  270. package/dist/components/record-time.js +38 -19
  271. package/dist/components/resizable.d.ts +7 -5
  272. package/dist/components/resizable.d.ts.map +1 -1
  273. package/dist/components/resizable.js +6 -6
  274. package/dist/components/scope-switcher.d.ts +2 -0
  275. package/dist/components/scope-switcher.d.ts.map +1 -1
  276. package/dist/components/scope-switcher.js +2 -2
  277. package/dist/components/scroll-area.d.ts +47 -11
  278. package/dist/components/scroll-area.d.ts.map +1 -1
  279. package/dist/components/scroll-area.js +72 -14
  280. package/dist/components/segmented-control.d.ts +82 -0
  281. package/dist/components/segmented-control.d.ts.map +1 -0
  282. package/dist/components/segmented-control.js +90 -0
  283. package/dist/components/select.d.ts +55 -15
  284. package/dist/components/select.d.ts.map +1 -1
  285. package/dist/components/select.js +62 -19
  286. package/dist/components/separator.d.ts +12 -5
  287. package/dist/components/separator.d.ts.map +1 -1
  288. package/dist/components/separator.js +11 -6
  289. package/dist/components/settings-facts.d.ts +34 -14
  290. package/dist/components/settings-facts.d.ts.map +1 -1
  291. package/dist/components/settings-facts.js +21 -12
  292. package/dist/components/settings-page.d.ts +4 -4
  293. package/dist/components/settings-page.js +5 -5
  294. package/dist/components/settings-section.d.ts +160 -34
  295. package/dist/components/settings-section.d.ts.map +1 -1
  296. package/dist/components/settings-section.js +92 -39
  297. package/dist/components/sheet.d.ts +47 -16
  298. package/dist/components/sheet.d.ts.map +1 -1
  299. package/dist/components/sheet.js +40 -19
  300. package/dist/components/sidebar-sections.d.ts +16 -12
  301. package/dist/components/sidebar-sections.d.ts.map +1 -1
  302. package/dist/components/sidebar-sections.js +30 -15
  303. package/dist/components/sidebar.d.ts +117 -21
  304. package/dist/components/sidebar.d.ts.map +1 -1
  305. package/dist/components/sidebar.js +180 -55
  306. package/dist/components/skeleton.d.ts +54 -8
  307. package/dist/components/skeleton.d.ts.map +1 -1
  308. package/dist/components/skeleton.js +44 -9
  309. package/dist/components/slider.d.ts +53 -11
  310. package/dist/components/slider.d.ts.map +1 -1
  311. package/dist/components/slider.js +71 -17
  312. package/dist/components/snippet.d.ts +57 -0
  313. package/dist/components/snippet.d.ts.map +1 -0
  314. package/dist/components/snippet.js +60 -0
  315. package/dist/components/sonner.d.ts +13 -14
  316. package/dist/components/sonner.d.ts.map +1 -1
  317. package/dist/components/sonner.js +25 -22
  318. package/dist/components/status-badge.d.ts +37 -11
  319. package/dist/components/status-badge.d.ts.map +1 -1
  320. package/dist/components/status-badge.js +63 -15
  321. package/dist/components/status-dot.d.ts +42 -11
  322. package/dist/components/status-dot.d.ts.map +1 -1
  323. package/dist/components/status-dot.js +40 -11
  324. package/dist/components/switch.d.ts +43 -12
  325. package/dist/components/switch.d.ts.map +1 -1
  326. package/dist/components/switch.js +42 -12
  327. package/dist/components/table-card.d.ts +21 -12
  328. package/dist/components/table-card.d.ts.map +1 -1
  329. package/dist/components/table-card.js +17 -9
  330. package/dist/components/table-layouts.d.ts +40 -8
  331. package/dist/components/table-layouts.d.ts.map +1 -1
  332. package/dist/components/table-layouts.js +52 -8
  333. package/dist/components/table-value.d.ts +4 -3
  334. package/dist/components/table-value.d.ts.map +1 -1
  335. package/dist/components/table-value.js +6 -5
  336. package/dist/components/table.d.ts +62 -25
  337. package/dist/components/table.d.ts.map +1 -1
  338. package/dist/components/table.js +62 -26
  339. package/dist/components/tabs.d.ts +86 -17
  340. package/dist/components/tabs.d.ts.map +1 -1
  341. package/dist/components/tabs.js +93 -22
  342. package/dist/components/text-link.d.ts +4 -1
  343. package/dist/components/text-link.d.ts.map +1 -1
  344. package/dist/components/text-link.js +4 -1
  345. package/dist/components/text-with-copy-button.d.ts +30 -0
  346. package/dist/components/text-with-copy-button.d.ts.map +1 -0
  347. package/dist/components/text-with-copy-button.js +32 -0
  348. package/dist/components/textarea.d.ts +40 -10
  349. package/dist/components/textarea.d.ts.map +1 -1
  350. package/dist/components/textarea.js +50 -11
  351. package/dist/components/theme-mode-switcher.d.ts +20 -3
  352. package/dist/components/theme-mode-switcher.d.ts.map +1 -1
  353. package/dist/components/theme-mode-switcher.js +23 -6
  354. package/dist/components/toggle-group.d.ts +28 -8
  355. package/dist/components/toggle-group.d.ts.map +1 -1
  356. package/dist/components/toggle-group.js +12 -6
  357. package/dist/components/toggle.d.ts +6 -3
  358. package/dist/components/toggle.d.ts.map +1 -1
  359. package/dist/components/toggle.js +10 -7
  360. package/dist/components/tooltip.d.ts +43 -12
  361. package/dist/components/tooltip.d.ts.map +1 -1
  362. package/dist/components/tooltip.js +45 -16
  363. package/dist/components/trend-badge.js +1 -1
  364. package/dist/components/update-card.js +1 -1
  365. package/dist/eslint/index.js +82 -0
  366. package/dist/eslint/rules/badge-is-static-label.js +93 -0
  367. package/dist/eslint/rules/button-icon-slot.js +102 -0
  368. package/dist/eslint/rules/button-link-for-navigation.js +146 -0
  369. package/dist/eslint/rules/button-no-aria-label-with-text.js +75 -0
  370. package/dist/eslint/rules/button-type-roles-only-in-buttons.js +83 -0
  371. package/dist/eslint/rules/choice-control-has-a-name.js +98 -0
  372. package/dist/eslint/rules/choice-group-in-fieldset.js +86 -0
  373. package/dist/eslint/rules/command-shortcut-single-owner.js +118 -0
  374. package/dist/eslint/rules/confirm-dialog-words.js +63 -0
  375. package/dist/eslint/rules/data-table-one-unsized-column.js +96 -0
  376. package/dist/eslint/rules/destructive-action-placement.js +69 -0
  377. package/dist/eslint/rules/disabled-choice-says-why.js +71 -0
  378. package/dist/eslint/rules/ellipsis-opens-a-dialog.js +110 -0
  379. package/dist/eslint/rules/input-group-owners.js +155 -0
  380. package/dist/eslint/rules/kbd-children-no-modifier-text.js +128 -0
  381. package/dist/eslint/rules/literal-text.js +41 -0
  382. package/dist/eslint/rules/middle-truncate-placement.js +69 -0
  383. package/dist/eslint/rules/no-bare-button-label.js +55 -0
  384. package/dist/eslint/rules/no-control-in-read-only-surface.js +106 -0
  385. package/dist/eslint/rules/no-hand-built-busy.js +104 -0
  386. package/dist/eslint/rules/no-hand-built-theme-picker.js +144 -0
  387. package/dist/eslint/rules/no-hand-built-tile.js +41 -0
  388. package/dist/eslint/rules/no-hand-formatted-date.js +87 -0
  389. package/dist/eslint/rules/no-hand-stacked-avatars.js +67 -0
  390. package/dist/eslint/rules/no-nested-collapse.js +60 -0
  391. package/dist/eslint/rules/no-search-in-form.js +47 -0
  392. package/dist/eslint/rules/no-shadcn-appearance-override.js +2 -16
  393. package/dist/eslint/rules/no-shell-prompt-in-snippet.js +74 -0
  394. package/dist/eslint/rules/no-stock-error-words.js +56 -0
  395. package/dist/eslint/rules/no-tooltip-around-labelled-field.js +72 -0
  396. package/dist/eslint/rules/no-weight-class-on-strong-in-type-role.js +57 -0
  397. package/dist/eslint/rules/one-submenu-level.js +43 -0
  398. package/dist/eslint/rules/one-toast-per-flow.js +91 -0
  399. package/dist/eslint/rules/option-count.js +167 -0
  400. package/dist/eslint/rules/page-command-link-not-render.js +43 -0
  401. package/dist/eslint/rules/progress-needs-name.js +57 -0
  402. package/dist/eslint/rules/settings-limit-in-footer.js +94 -0
  403. package/dist/eslint/rules/skeleton-in-region.js +80 -0
  404. package/dist/eslint/rules/sortable-heading-uses-sort.js +79 -0
  405. package/dist/eslint/rules/table-cell-inset-owner.js +107 -0
  406. package/dist/eslint/rules/tabs-selection-is-controlled.js +47 -0
  407. package/dist/eslint/rules/tooltip-only-arrow.js +38 -0
  408. package/dist/eslint/rules/tooltip-trigger-accessible-name.js +114 -0
  409. package/dist/eslint/strict-design-system.js +21 -7
  410. package/dist/index.d.ts +13 -13
  411. package/dist/index.d.ts.map +1 -1
  412. package/dist/index.js +12 -13
  413. package/dist/internal/assistant-ui/attachment.d.ts.map +1 -1
  414. package/dist/internal/assistant-ui/attachment.js +2 -2
  415. package/dist/internal/assistant-ui/reasoning.d.ts +1 -1
  416. package/dist/internal/assistant-ui/reasoning.d.ts.map +1 -1
  417. package/dist/internal/assistant-ui/tool-fallback.js +1 -1
  418. package/dist/internal/assistant-ui/tool-group.d.ts +1 -1
  419. package/dist/internal/assistant-ui/tool-group.d.ts.map +1 -1
  420. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts +2 -3
  421. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts.map +1 -1
  422. package/dist/internal/assistant-ui/tooltip-icon-button.js +1 -1
  423. package/dist/internal/catalog-list.js +2 -2
  424. package/dist/internal/collection-note.d.ts +23 -0
  425. package/dist/internal/collection-note.d.ts.map +1 -0
  426. package/dist/internal/collection-note.js +17 -0
  427. package/dist/internal/collection-rail.d.ts +57 -0
  428. package/dist/internal/collection-rail.d.ts.map +1 -0
  429. package/dist/internal/collection-rail.js +33 -0
  430. package/dist/internal/company-logo.d.ts +18 -0
  431. package/dist/internal/company-logo.d.ts.map +1 -0
  432. package/dist/internal/company-logo.js +14 -0
  433. package/dist/internal/control-name.d.ts +12 -0
  434. package/dist/internal/control-name.d.ts.map +1 -0
  435. package/dist/internal/control-name.js +1 -0
  436. package/dist/internal/diff-line.d.ts +9 -0
  437. package/dist/internal/diff-line.d.ts.map +1 -0
  438. package/dist/internal/diff-line.js +8 -0
  439. package/dist/internal/empty.d.ts +8 -4
  440. package/dist/internal/empty.d.ts.map +1 -1
  441. package/dist/internal/empty.js +14 -8
  442. package/dist/internal/field-frame.d.ts +33 -0
  443. package/dist/internal/field-frame.d.ts.map +1 -0
  444. package/dist/internal/field-frame.js +20 -0
  445. package/dist/internal/final-focus.d.ts +8 -0
  446. package/dist/internal/final-focus.d.ts.map +1 -0
  447. package/dist/internal/final-focus.js +10 -0
  448. package/dist/internal/footer-strip.d.ts.map +1 -1
  449. package/dist/internal/footer-strip.js +3 -1
  450. package/dist/internal/form-submit.d.ts +9 -5
  451. package/dist/internal/form-submit.d.ts.map +1 -1
  452. package/dist/internal/form-submit.js +31 -2
  453. package/dist/internal/input-box.d.ts +26 -0
  454. package/dist/internal/input-box.d.ts.map +1 -0
  455. package/dist/internal/input-box.js +59 -0
  456. package/dist/internal/menu-surface.d.ts +10 -3
  457. package/dist/internal/menu-surface.d.ts.map +1 -1
  458. package/dist/internal/menu-surface.js +10 -3
  459. package/dist/internal/notice.d.ts +25 -0
  460. package/dist/internal/notice.d.ts.map +1 -0
  461. package/dist/internal/notice.js +33 -0
  462. package/dist/internal/overlay-stem.d.ts +5 -0
  463. package/dist/internal/overlay-stem.d.ts.map +1 -0
  464. package/dist/internal/overlay-stem.js +7 -0
  465. package/dist/internal/phone-sheet.d.ts +4 -0
  466. package/dist/internal/phone-sheet.d.ts.map +1 -0
  467. package/dist/internal/phone-sheet.js +2 -0
  468. package/dist/internal/present-content.d.ts +3 -0
  469. package/dist/internal/present-content.d.ts.map +1 -0
  470. package/dist/internal/present-content.js +1 -0
  471. package/dist/internal/record-menu-items.d.ts +4 -3
  472. package/dist/internal/record-menu-items.d.ts.map +1 -1
  473. package/dist/internal/record-menu-items.js +21 -6
  474. package/dist/internal/settings-save.d.ts +9 -2
  475. package/dist/internal/settings-save.d.ts.map +1 -1
  476. package/dist/internal/settings-save.js +9 -6
  477. package/dist/internal/table-compact-line.d.ts +38 -0
  478. package/dist/internal/table-compact-line.d.ts.map +1 -0
  479. package/dist/internal/table-compact-line.js +35 -0
  480. package/dist/internal/title-when-cut.d.ts +8 -0
  481. package/dist/internal/title-when-cut.d.ts.map +1 -0
  482. package/dist/internal/title-when-cut.js +22 -0
  483. package/dist/internal/unsaved-guard.d.ts +18 -0
  484. package/dist/internal/unsaved-guard.d.ts.map +1 -0
  485. package/dist/internal/unsaved-guard.js +31 -0
  486. package/dist/lib/merge-tokens.generated.js +2 -2
  487. package/dist/showcase/foundations.d.ts.map +1 -1
  488. package/dist/showcase/foundations.js +10 -2
  489. package/dist/showcase/specimens/actions.d.ts +2 -0
  490. package/dist/showcase/specimens/actions.d.ts.map +1 -1
  491. package/dist/showcase/specimens/actions.js +30 -5
  492. package/dist/showcase/specimens/charts.d.ts.map +1 -1
  493. package/dist/showcase/specimens/charts.js +22 -13
  494. package/dist/showcase/specimens/choices.d.ts +14 -3
  495. package/dist/showcase/specimens/choices.d.ts.map +1 -1
  496. package/dist/showcase/specimens/choices.js +93 -13
  497. package/dist/showcase/specimens/compositions.d.ts.map +1 -1
  498. package/dist/showcase/specimens/compositions.js +136 -23
  499. package/dist/showcase/specimens/data.d.ts +12 -7
  500. package/dist/showcase/specimens/data.d.ts.map +1 -1
  501. package/dist/showcase/specimens/data.js +139 -35
  502. package/dist/showcase/specimens/feedback.d.ts +2 -0
  503. package/dist/showcase/specimens/feedback.d.ts.map +1 -1
  504. package/dist/showcase/specimens/feedback.js +39 -15
  505. package/dist/showcase/specimens/index.d.ts +20 -12
  506. package/dist/showcase/specimens/index.d.ts.map +1 -1
  507. package/dist/showcase/specimens/inputs.d.ts +4 -2
  508. package/dist/showcase/specimens/inputs.d.ts.map +1 -1
  509. package/dist/showcase/specimens/inputs.js +62 -19
  510. package/dist/showcase/specimens/menus.d.ts +0 -1
  511. package/dist/showcase/specimens/menus.d.ts.map +1 -1
  512. package/dist/showcase/specimens/menus.js +47 -18
  513. package/dist/showcase/specimens/navigation.d.ts +6 -4
  514. package/dist/showcase/specimens/navigation.d.ts.map +1 -1
  515. package/dist/showcase/specimens/navigation.js +61 -32
  516. package/dist/showcase/specimens/other.d.ts +1 -3
  517. package/dist/showcase/specimens/other.d.ts.map +1 -1
  518. package/dist/showcase/specimens/other.js +17 -13
  519. package/dist/showcase/specimens/status.d.ts +4 -1
  520. package/dist/showcase/specimens/status.d.ts.map +1 -1
  521. package/dist/showcase/specimens/status.js +64 -11
  522. package/dist/showcase/usage.generated.d.ts +1 -1
  523. package/dist/showcase/usage.generated.d.ts.map +1 -1
  524. package/dist/showcase/usage.generated.js +637 -549
  525. package/dist/standalone/index.js +1 -1
  526. package/dist/styles/components.css +13 -13
  527. package/dist/styles/globals.css +25 -0
  528. package/package.json +2 -3
  529. package/dist/components/approval-row.d.ts +0 -34
  530. package/dist/components/approval-row.d.ts.map +0 -1
  531. package/dist/components/approval-row.js +0 -27
  532. package/dist/components/channel-view.d.ts +0 -112
  533. package/dist/components/channel-view.d.ts.map +0 -1
  534. package/dist/components/channel-view.js +0 -84
  535. package/dist/components/dashboard-shell.d.ts +0 -51
  536. package/dist/components/dashboard-shell.d.ts.map +0 -1
  537. package/dist/components/dashboard-shell.js +0 -89
  538. package/dist/components/direction.d.ts +0 -2
  539. package/dist/components/direction.d.ts.map +0 -1
  540. package/dist/components/direction.js +0 -1
  541. package/dist/components/expandable-block.d.ts +0 -20
  542. package/dist/components/expandable-block.d.ts.map +0 -1
  543. package/dist/components/expandable-block.js +0 -32
  544. package/dist/components/form.d.ts +0 -42
  545. package/dist/components/form.d.ts.map +0 -1
  546. package/dist/components/form.js +0 -91
  547. package/dist/components/label-system.d.ts +0 -17
  548. package/dist/components/label-system.d.ts.map +0 -1
  549. package/dist/components/label-system.js +0 -21
  550. package/dist/components/memory-item.d.ts +0 -21
  551. package/dist/components/memory-item.d.ts.map +0 -1
  552. package/dist/components/memory-item.js +0 -18
  553. package/dist/components/menubar.d.ts +0 -43
  554. package/dist/components/menubar.d.ts.map +0 -1
  555. package/dist/components/menubar.js +0 -69
  556. package/dist/components/navigation-menu.d.ts +0 -26
  557. package/dist/components/navigation-menu.d.ts.map +0 -1
  558. package/dist/components/navigation-menu.js +0 -45
  559. package/dist/components/pagination.d.ts +0 -33
  560. package/dist/components/pagination.d.ts.map +0 -1
  561. package/dist/components/pagination.js +0 -41
  562. package/dist/components/plugin-slot-boundary.d.ts +0 -42
  563. package/dist/components/plugin-slot-boundary.d.ts.map +0 -1
  564. package/dist/components/plugin-slot-boundary.js +0 -41
  565. package/dist/components/status-row.d.ts +0 -32
  566. package/dist/components/status-row.d.ts.map +0 -1
  567. package/dist/components/status-row.js +0 -35
@@ -1,20 +1,46 @@
1
+ import type * as React from "react";
1
2
  import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
2
3
  /**
3
4
  * Sections that open and close under their headings.
4
5
  *
5
6
  * @family Other
6
- * @when Optional or advanced content in named sections, such as the questions of a help page.
7
- * @instead One piece of supporting detail is `Disclosure`. A long block cut short is
8
- * `ExpandableBlock`. The page's main answer is never hidden in one.
9
- * @behaviour Related sections may stay open together; exclusive ones open one at a time. The
10
- * trigger's chevron turns when open.
11
- * @words Each trigger names its topic as a noun phrase or a question a person asks.
12
- * @access Each trigger is a `button` with `aria-expanded` controlling its panel; headings keep the
13
- * page's outline.
7
+ * @when “Use Collapse for optional, advanced, or repetitive content that most users skip on most visits (FAQ, advanced settings, request payload preview).” (https://vercel.com/geist/collapse)
8
+ * “For top-level structure that every user reads, use page sections with regular headings; collapsing primary content hides what the page is about.” (https://vercel.com/geist/collapse)
9
+ * Ours: Geist's `CollapseGroup` is `Accordion`: named sections such as a help page's questions or
10
+ * advanced settings.
11
+ * @instead “Single Collapse for one optional block. `CollapseGroup` for a related set; switch to `Tabs` when the items are sibling views, not optional drill-downs.” (https://vercel.com/geist/collapse)
12
+ * Ours: one piece of supporting detail is `Disclosure`, and a single optional block is
13
+ * `Collapsible`.
14
+ * @behaviour “Default state is closed unless the first-time visitor must read the content to act.” (https://vercel.com/geist/collapse)
15
+ * “Inside a `CollapseGroup`, allow only one panel open at a time when items are mutually exclusive; allow multiple when items are independent.” (https://vercel.com/geist/collapse)
16
+ * “Animate the open/close transition; jump-cuts make the page feel like it teleported.” (https://vercel.com/geist/collapse)
17
+ * “Don’t nest Collapse more than one level deep. Two-level nesting hides too much and breaks the keyboard tab path.” (https://vercel.com/geist/collapse)
18
+ * Ours: a flat list divided by 1 px lines, closed at the top and under every section, with no fill, no
19
+ * card and no hover change. A section is a heading row with the title at the start and a 16 px
20
+ * chevron at the end that points right while closed and down while open. `size` is `default` (a
21
+ * 24 px semibold title, an 84 px row) or `small` (a 16 px medium title, a 48 px row). Colour is
22
+ * neutral only, in every state. Exclusive sections open one at a time and the open one can be
23
+ * closed; independent ones stay open together with `multiple`. The panel animates its height, and
24
+ * under reduced motion it jumps. An accordion never nests in another.
25
+ * @words “Heading is Title Case and names the topic, not the action (`Advanced Settings`, not `Show Advanced Settings`).” (https://vercel.com/geist/collapse)
26
+ * “Body is sentence case prose with normal section formatting; treat the panel as a small page, not a tooltip.” (https://vercel.com/geist/collapse)
27
+ * “Don’t put primary destructive actions inside a closed Collapse; the user has to click twice to reach the warning.” (https://vercel.com/geist/collapse)
28
+ * Ours: the trigger is required and names its topic as a noun phrase or a question a person asks, in
29
+ * sentence case, not Title Case: *Advanced settings*, never *Show advanced settings*.
30
+ * @access “The trigger is a `<button>` with `aria-expanded` that flips on toggle and `aria-controls` pointing at the panel id.” (https://vercel.com/geist/collapse)
31
+ * “Enter and Space toggle. Don’t bind any other key globally; arrow keys move focus inside the panel content.” (https://vercel.com/geist/collapse)
32
+ * “Render the panel content in the DOM when closed (with `hidden` or visibility) so search and find-in-page still hit it; lazy-render only for expensive content.” (https://vercel.com/geist/collapse)
33
+ * Ours: a closed panel stays in the page, hidden until found, so find-in-page opens it; pass
34
+ * `hiddenUntilFound={false}` on a heavy panel to mount it only when open. Headings keep the page's
35
+ * outline.
14
36
  */
15
- declare function Accordion({ className, ...props }: AccordionPrimitive.Root.Props): import("react").JSX.Element;
16
- declare function AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props): import("react").JSX.Element;
17
- declare function AccordionTrigger({ className, children, ...props }: AccordionPrimitive.Trigger.Props): import("react").JSX.Element;
18
- declare function AccordionContent({ className, children, ...props }: AccordionPrimitive.Panel.Props): import("react").JSX.Element;
37
+ declare function Accordion({ className, size, ...props }: AccordionPrimitive.Root.Props & {
38
+ size?: "default" | "small";
39
+ }): React.JSX.Element;
40
+ declare function AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props): React.JSX.Element;
41
+ declare function AccordionTrigger({ className, children, ...props }: Omit<AccordionPrimitive.Trigger.Props, "children"> & {
42
+ children: React.ReactNode;
43
+ }): React.JSX.Element;
44
+ declare function AccordionContent({ className, children, hiddenUntilFound, ...props }: AccordionPrimitive.Panel.Props): React.JSX.Element;
19
45
  export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
20
46
  //# sourceMappingURL=accordion.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../src/components/accordion.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAK3E;;;;;;;;;;;;GAYG;AACH,iBAAS,SAAS,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,+BAQxE;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,+BAQ5E;AAED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,+BAmB5F;AAED,iBAAS,gBAAgB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,CAAC,KAAK,CAAC,KAAK,+BAiB1F;AAED,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"accordion.d.ts","sourceRoot":"","sources":["../../src/components/accordion.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAEpC,OAAO,EAAE,SAAS,IAAI,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAK3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,GAAG;IAAE,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAA;CAAE,qBAShE;AAED,iBAAS,aAAa,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,qBAQ5E;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,qBAmBpF;AAED,iBAAS,gBAAgB,CAAC,EACxB,SAAS,EACT,QAAQ,EACR,gBAAuB,EACvB,GAAG,KAAK,EACT,EAAE,kBAAkB,CAAC,KAAK,CAAC,KAAK,qBAkBhC;AAED,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,30 +1,51 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion";
3
+ import { ChevronRightIcon } from "lucide-react";
3
4
  import { cn } from "../lib/utils.js";
4
- import { ChevronDownIcon } from "lucide-react";
5
5
  /**
6
6
  * Sections that open and close under their headings.
7
7
  *
8
8
  * @family Other
9
- * @when Optional or advanced content in named sections, such as the questions of a help page.
10
- * @instead One piece of supporting detail is `Disclosure`. A long block cut short is
11
- * `ExpandableBlock`. The page's main answer is never hidden in one.
12
- * @behaviour Related sections may stay open together; exclusive ones open one at a time. The
13
- * trigger's chevron turns when open.
14
- * @words Each trigger names its topic as a noun phrase or a question a person asks.
15
- * @access Each trigger is a `button` with `aria-expanded` controlling its panel; headings keep the
16
- * page's outline.
9
+ * @when “Use Collapse for optional, advanced, or repetitive content that most users skip on most visits (FAQ, advanced settings, request payload preview).” (https://vercel.com/geist/collapse)
10
+ * “For top-level structure that every user reads, use page sections with regular headings; collapsing primary content hides what the page is about.” (https://vercel.com/geist/collapse)
11
+ * Ours: Geist's `CollapseGroup` is `Accordion`: named sections such as a help page's questions or
12
+ * advanced settings.
13
+ * @instead “Single Collapse for one optional block. `CollapseGroup` for a related set; switch to `Tabs` when the items are sibling views, not optional drill-downs.” (https://vercel.com/geist/collapse)
14
+ * Ours: one piece of supporting detail is `Disclosure`, and a single optional block is
15
+ * `Collapsible`.
16
+ * @behaviour “Default state is closed unless the first-time visitor must read the content to act.” (https://vercel.com/geist/collapse)
17
+ * “Inside a `CollapseGroup`, allow only one panel open at a time when items are mutually exclusive; allow multiple when items are independent.” (https://vercel.com/geist/collapse)
18
+ * “Animate the open/close transition; jump-cuts make the page feel like it teleported.” (https://vercel.com/geist/collapse)
19
+ * “Don’t nest Collapse more than one level deep. Two-level nesting hides too much and breaks the keyboard tab path.” (https://vercel.com/geist/collapse)
20
+ * Ours: a flat list divided by 1 px lines, closed at the top and under every section, with no fill, no
21
+ * card and no hover change. A section is a heading row with the title at the start and a 16 px
22
+ * chevron at the end that points right while closed and down while open. `size` is `default` (a
23
+ * 24 px semibold title, an 84 px row) or `small` (a 16 px medium title, a 48 px row). Colour is
24
+ * neutral only, in every state. Exclusive sections open one at a time and the open one can be
25
+ * closed; independent ones stay open together with `multiple`. The panel animates its height, and
26
+ * under reduced motion it jumps. An accordion never nests in another.
27
+ * @words “Heading is Title Case and names the topic, not the action (`Advanced Settings`, not `Show Advanced Settings`).” (https://vercel.com/geist/collapse)
28
+ * “Body is sentence case prose with normal section formatting; treat the panel as a small page, not a tooltip.” (https://vercel.com/geist/collapse)
29
+ * “Don’t put primary destructive actions inside a closed Collapse; the user has to click twice to reach the warning.” (https://vercel.com/geist/collapse)
30
+ * Ours: the trigger is required and names its topic as a noun phrase or a question a person asks, in
31
+ * sentence case, not Title Case: *Advanced settings*, never *Show advanced settings*.
32
+ * @access “The trigger is a `<button>` with `aria-expanded` that flips on toggle and `aria-controls` pointing at the panel id.” (https://vercel.com/geist/collapse)
33
+ * “Enter and Space toggle. Don’t bind any other key globally; arrow keys move focus inside the panel content.” (https://vercel.com/geist/collapse)
34
+ * “Render the panel content in the DOM when closed (with `hidden` or visibility) so search and find-in-page still hit it; lazy-render only for expensive content.” (https://vercel.com/geist/collapse)
35
+ * Ours: a closed panel stays in the page, hidden until found, so find-in-page opens it; pass
36
+ * `hiddenUntilFound={false}` on a heavy panel to mount it only when open. Headings keep the page's
37
+ * outline.
17
38
  */
18
- function Accordion({ className, ...props }) {
19
- return (_jsx(AccordionPrimitive.Root, { "data-slot": "accordion", className: cn("flex w-full flex-col", className), ...props }));
39
+ function Accordion({ className, size = "default", ...props }) {
40
+ return (_jsx(AccordionPrimitive.Root, { "data-slot": "accordion", "data-size": size, className: cn("group/accordion flex w-full flex-col border-t", className), ...props }));
20
41
  }
21
42
  function AccordionItem({ className, ...props }) {
22
- return (_jsx(AccordionPrimitive.Item, { "data-slot": "accordion-item", className: cn("not-last:border-b", className), ...props }));
43
+ return (_jsx(AccordionPrimitive.Item, { "data-slot": "accordion-item", className: cn("border-b", className), ...props }));
23
44
  }
24
45
  function AccordionTrigger({ className, children, ...props }) {
25
- return (_jsx(AccordionPrimitive.Header, { className: "flex", children: _jsxs(AccordionPrimitive.Trigger, { "data-slot": "accordion-trigger", className: cn("nc-transition-paint group/accordion-trigger relative flex min-h-touch-target flex-1 items-start justify-between rounded-sm border border-transparent py-2.5 text-left text-sm font-medium hover:underline aria-disabled:pointer-events-none aria-disabled:opacity-50 [@media(hover:hover)_and_(pointer:fine)]:min-h-0 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground", className), ...props, children: [children, _jsx(ChevronDownIcon, { "data-slot": "accordion-trigger-icon", className: "nc-transition-transform pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:rotate-180" })] }) }));
46
+ return (_jsx(AccordionPrimitive.Header, { className: "flex", children: _jsxs(AccordionPrimitive.Trigger, { "data-slot": "accordion-trigger", className: cn("nc-transition-paint group/accordion-trigger flex min-h-touch-target flex-1 items-center justify-between gap-4 rounded-sm py-6.5 text-left text-heading-md aria-disabled:pointer-events-none aria-disabled:opacity-50 group-data-[size=small]/accordion:py-3 group-data-[size=small]/accordion:text-body-md group-data-[size=small]/accordion:font-medium [@media(hover:hover)_and_(pointer:fine)]:min-h-0", className), ...props, children: [children, _jsx(ChevronRightIcon, { "data-slot": "accordion-trigger-icon", className: "nc-transition-transform pointer-events-none size-4 shrink-0 group-aria-expanded/accordion-trigger:rotate-90" })] }) }));
26
47
  }
27
- function AccordionContent({ className, children, ...props }) {
28
- return (_jsx(AccordionPrimitive.Panel, { "data-slot": "accordion-content", className: "overflow-hidden text-sm", ...props, children: _jsx("div", { className: cn("h-(--accordion-panel-height) pt-0 pb-2.5 data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4", className), children: children }) }));
48
+ function AccordionContent({ className, children, hiddenUntilFound = true, ...props }) {
49
+ return (_jsx(AccordionPrimitive.Panel, { "data-slot": "accordion-content", className: "h-(--accordion-panel-height) overflow-hidden text-body-md transition-[height] duration-[var(--nc-duration-open)] ease-[var(--nc-ease-out-strong)] data-ending-style:h-0 data-starting-style:h-0 motion-reduce:transition-none", hiddenUntilFound: hiddenUntilFound, ...props, children: _jsx("div", { className: cn("pb-4 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4", className), children: children }) }));
29
50
  }
30
51
  export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
@@ -1,4 +1,4 @@
1
- import type { ComponentProps, ReactElement, ReactNode } from "react";
1
+ import type { ComponentProps, ReactNode } from "react";
2
2
  import type { MenuCommand } from "./action-menu.js";
3
3
  import { type MenuChoiceRowProps } from "./menu-choice-row.js";
4
4
  import type { PageCommandAction } from "./page-actions.js";
@@ -16,26 +16,29 @@ export type AccountIdentity = {
16
16
  /** The name a person recognises as theirs. */
17
17
  name: string;
18
18
  /**
19
- * Under the name: an email, the scope they are working in, a notice. The
20
- * trigger, one sidebar row high, shows the first; the menu's header shows
21
- * them all.
19
+ * Under the name in the menu's header: an email, the scope they are working
20
+ * in. The trigger shows none of them.
22
21
  */
23
22
  lines?: ReactNode[];
23
+ /**
24
+ * A condition the person must see without opening the menu, such as the
25
+ * account being suspended: the trigger shows it under the name, and the
26
+ * menu's header shows it first.
27
+ */
28
+ notice?: ReactNode;
24
29
  };
25
30
  export type AccountMenuIdentityProps = {
26
31
  className?: string;
27
32
  identity: AccountIdentity;
28
33
  /** The picture alone, for a navigation rail drawn too narrow for the name. */
29
34
  pictureOnly?: boolean;
30
- /** `lg` is the menu's own header; `default` is the trigger. */
31
- size?: "default" | "lg";
32
35
  };
33
36
  /**
34
- * The account's avatar beside its name and lines. The trigger shows it with the
35
- * first line, and the menu opens on it with every line, so a person sees the
36
- * same block in both places.
37
+ * Whose account it is at the sidebar's foot, as Vercel draws it: the picture,
38
+ * the name with any notice under it, and the three dots at the end. The
39
+ * account menu's trigger draws it, and so does a sample of the Portal's column.
37
40
  */
38
- export declare function AccountMenuIdentity({ className, identity, pictureOnly, size, }: AccountMenuIdentityProps): import("react").JSX.Element;
41
+ export declare function AccountMenuIdentity({ className, identity, pictureOnly, }: AccountMenuIdentityProps): import("react").JSX.Element;
39
42
  export type AccountMenuCommand = MenuCommand & {
40
43
  /** A reading at the row's end: "62% left". */
41
44
  value?: ReactNode;
@@ -43,7 +46,6 @@ export type AccountMenuCommand = MenuCommand & {
43
46
  /** A product's own exclusive setting, in a submenu: Alveare's presence. */
44
47
  export type AccountMenuChoice = {
45
48
  label: string;
46
- icon: ReactElement;
47
49
  value: string;
48
50
  /** Each option's name, its mark, and one muted line under the name when the name alone does not say what it is. */
49
51
  options: readonly {
@@ -75,19 +77,17 @@ export type AccountMenuProps = {
75
77
  };
76
78
  /** Applies at once and keeps the menu open. */
77
79
  theme: ComponentProps<typeof ThemeModeMenu>;
78
- language?: MenuChoiceRowProps<string> & {
79
- icon: ReactElement;
80
- };
80
+ language?: MenuChoiceRowProps<string>;
81
81
  choices?: readonly AccountMenuChoice[];
82
82
  commands?: readonly AccountMenuCommand[];
83
+ /** Where the product's commands stand: first, above Theme, or after its choices. */
84
+ commandsAt?: "end" | "start";
83
85
  signOut: AccountMenuSignOut;
84
86
  /**
85
87
  * The trigger shows the picture alone, for a navigation rail drawn too narrow
86
88
  * for the name; the menu still opens on the whole identity.
87
89
  */
88
90
  pictureOnly?: boolean;
89
- /** The element the trigger renders as, when a shell has its own button. */
90
- triggerRender?: ReactElement;
91
91
  align?: "center" | "end" | "start";
92
92
  side?: "bottom" | "left" | "right" | "top";
93
93
  /** Runs when the menu opens or closes, for a shell that records where it was. */
@@ -100,9 +100,9 @@ export type AccountMenuProps = {
100
100
  * @family Menus
101
101
  * @when The account at the sidebar's foot in the Portal, Nadia and Alveare: the gear to the account's settings, Theme, Language, a product's own settings, its commands, and Sign out.
102
102
  * @instead A record's or a page's commands are an ActionMenu; a setting with more than a few options or one that needs a Save belongs on a SettingsPage.
103
- * @behaviour The menu opens upward on the identity. In order: the gear, Theme, Language, the product's choices as submenus, its commands with any reading at their end, and Sign out last in the error colour. Theme and Language apply at once and keep the menu open. While signing out, Sign out says its pending word, the menu stays open and the trigger is locked; a failure shows under it. A Sign out that `confirms` closes the menu instead, for the product's own confirmation.
103
+ * @behaviour The menu opens 6 px above its trigger, 288 px wide, as Vercel's does: a header of the name and every line under it with the gear at its end, one divider, then 36 px rows, each its label leading and its icon or control trailing: Theme and Language as small round pills, the product's choices as submenus, its commands with any reading before their icon, and Sign out last. Theme and Language apply at once and keep the menu open. While signing out, Sign out says its pending word, the menu stays open and the trigger is locked; a failure shows under it. A Sign out that `confirms` closes the menu instead, for the product's own confirmation.
104
104
  * @words The menu's name ("Account"), the person's name and lines, then each row's noun or verb from the product's catalogue: "Theme", "Language", "Usage", "Sign out" and "Signing out".
105
105
  * @access The trigger and the menu are named "{label}: {name}"; the gear carries its label; the pending sign-out is aria-busy and announced through a status; a failure is an alert.
106
106
  */
107
- export declare function AccountMenu({ align, choices, commands, identity, label, language, onOpenChange, pictureOnly, settings, side, signOut, theme, triggerRender, }: AccountMenuProps): import("react").JSX.Element;
107
+ export declare function AccountMenu({ align, choices, commands, commandsAt, identity, label, language, onOpenChange, pictureOnly, settings, side, signOut, theme, }: AccountMenuProps): import("react").JSX.Element;
108
108
  //# sourceMappingURL=account-menu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"account-menu.d.ts","sourceRoot":"","sources":["../../src/components/account-menu.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"account-menu.d.ts","sourceRoot":"","sources":["../../src/components/account-menu.tsx"],"names":[],"mappings":"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"}
@@ -1,22 +1,22 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { ChevronsUpDown, LogOut, Settings, UserRound } from "lucide-react";
3
+ import { Ellipsis, LogOut, Settings, UserRound } from "lucide-react";
4
4
  import { Avatar, AvatarFallback, AvatarImage } from "./avatar.js";
5
- import { DropdownMenu, DropdownMenuCommand, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "./dropdown-menu.js";
5
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from "./dropdown-menu.js";
6
6
  import { FieldError } from "./field.js";
7
7
  import { MenuChoiceRow } from "./menu-choice-row.js";
8
8
  import { PendingLabel } from "./pending-label.js";
9
9
  import { bodyBeyondTitle } from "./product-message.js";
10
10
  import { ThemeModeMenu } from "./theme-mode-switcher.js";
11
- import { MenuCommandRow, menuItemAction } from "../internal/record-menu-items.js";
11
+ import { menuItemAction } from "../internal/record-menu-items.js";
12
12
  import { cn } from "../lib/utils.js";
13
13
  /**
14
- * The account's avatar beside its name and lines. The trigger shows it with the
15
- * first line, and the menu opens on it with every line, so a person sees the
16
- * same block in both places.
14
+ * Whose account it is at the sidebar's foot, as Vercel draws it: the picture,
15
+ * the name with any notice under it, and the three dots at the end. The
16
+ * account menu's trigger draws it, and so does a sample of the Portal's column.
17
17
  */
18
- export function AccountMenuIdentity({ className, identity, pictureOnly = false, size = "default", }) {
19
- return (_jsxs("span", { className: cn("flex min-w-0 items-center gap-2 text-left text-sm", className), "data-slot": "account-menu-identity", children: [_jsxs(Avatar, { "aria-hidden": "true", size: size === "lg" ? "default" : "sm", children: [identity.image ? _jsx(AvatarImage, { alt: "", src: identity.image }) : null, _jsx(AvatarFallback, { children: identity.initials || _jsx(UserRound, { "aria-hidden": "true", className: "size-3/5" }) })] }), pictureOnly ? null : (_jsxs("span", { className: "grid min-w-0 flex-1 gap-0.5 leading-tight", children: [_jsx("span", { className: "truncate font-medium text-foreground", children: identity.name }), (size === "lg" ? identity.lines : identity.lines?.slice(0, 1))?.map((line, index) => (_jsx("span", { className: "truncate text-xs font-normal text-muted-foreground", children: line }, index)))] }))] }));
18
+ export function AccountMenuIdentity({ className, identity, pictureOnly = false, }) {
19
+ return (_jsxs("span", { className: cn("flex min-w-0 items-center gap-2 text-left text-sm", !pictureOnly && "flex-1", className), "data-slot": "account-menu-identity", children: [_jsxs(Avatar, { className: "size-5", decorative: true, size: "sm", children: [identity.image ? _jsx(AvatarImage, { alt: "", src: identity.image }) : null, _jsx(AvatarFallback, { children: identity.initials || _jsx(UserRound, { "aria-hidden": "true", className: "size-3/5" }) })] }), pictureOnly ? null : (_jsxs(_Fragment, { children: [_jsxs("span", { className: "grid min-w-0 flex-1 leading-tight", children: [_jsx("span", { className: "truncate text-foreground", children: identity.name }), identity.notice ? _jsx("span", { className: "truncate text-xs", children: identity.notice }) : null] }), _jsx("span", { "aria-hidden": "true", className: "grid size-6 shrink-0 place-content-center rounded-full border border-border bg-popover text-muted-foreground transition-colors group-hover/account:text-foreground group-data-[popup-open]/account:text-foreground", children: _jsx(Ellipsis, { className: "size-3" }) })] }))] }));
20
20
  }
21
21
  /**
22
22
  * The account menu at the foot of a shell's navigation: whose account it is,
@@ -25,20 +25,24 @@ export function AccountMenuIdentity({ className, identity, pictureOnly = false,
25
25
  * @family Menus
26
26
  * @when The account at the sidebar's foot in the Portal, Nadia and Alveare: the gear to the account's settings, Theme, Language, a product's own settings, its commands, and Sign out.
27
27
  * @instead A record's or a page's commands are an ActionMenu; a setting with more than a few options or one that needs a Save belongs on a SettingsPage.
28
- * @behaviour The menu opens upward on the identity. In order: the gear, Theme, Language, the product's choices as submenus, its commands with any reading at their end, and Sign out last in the error colour. Theme and Language apply at once and keep the menu open. While signing out, Sign out says its pending word, the menu stays open and the trigger is locked; a failure shows under it. A Sign out that `confirms` closes the menu instead, for the product's own confirmation.
28
+ * @behaviour The menu opens 6 px above its trigger, 288 px wide, as Vercel's does: a header of the name and every line under it with the gear at its end, one divider, then 36 px rows, each its label leading and its icon or control trailing: Theme and Language as small round pills, the product's choices as submenus, its commands with any reading before their icon, and Sign out last. Theme and Language apply at once and keep the menu open. While signing out, Sign out says its pending word, the menu stays open and the trigger is locked; a failure shows under it. A Sign out that `confirms` closes the menu instead, for the product's own confirmation.
29
29
  * @words The menu's name ("Account"), the person's name and lines, then each row's noun or verb from the product's catalogue: "Theme", "Language", "Usage", "Sign out" and "Signing out".
30
30
  * @access The trigger and the menu are named "{label}: {name}"; the gear carries its label; the pending sign-out is aria-busy and announced through a status; a failure is an alert.
31
31
  */
32
- export function AccountMenu({ align = "start", choices = [], commands = [], identity, label, language, onOpenChange, pictureOnly = false, settings, side = "top", signOut, theme, triggerRender, }) {
32
+ export function AccountMenu({ align = "start", choices = [], commands = [], commandsAt = "end", identity, label, language, onOpenChange, pictureOnly = false, settings, side = "top", signOut, theme, }) {
33
33
  const name = `${label}: ${identity.name}`;
34
- return (_jsxs(DropdownMenu, { onOpenChange: onOpenChange, children: [_jsxs(DropdownMenuTrigger, { "aria-label": name, disabled: signOut.pending, render: triggerRender ?? (_jsx("button", { className: "flex w-full min-w-0 items-center gap-2 rounded-sm p-1.5 text-left outline-none hover:bg-accent focus-visible:nc-focus-outline focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 data-[popup-open]:bg-accent", type: "button" })), children: [_jsx(AccountMenuIdentity, { className: pictureOnly ? undefined : "flex-1", identity: identity, pictureOnly: pictureOnly }), pictureOnly ? null : (_jsx(ChevronsUpDown, { "aria-hidden": "true", className: "ml-auto size-4 shrink-0 text-muted-foreground" }))] }), _jsxs(DropdownMenuContent, { align: align, "aria-label": name, className: "w-72 max-w-[calc(100vw-2rem)]", density: "comfortable", side: side, sideOffset: 8, children: [_jsxs(DropdownMenuGroup, { className: "flex min-w-0 items-center gap-1 pr-1.5", children: [_jsx(AccountMenuIdentity, { className: "min-w-0 flex-1 px-2 py-2", identity: identity, size: "lg" }), settings ? (_jsx(DropdownMenuItem, { "aria-label": settings.label, iconOnly: true, ...menuItemAction(settings), children: _jsx(Settings, { "aria-hidden": "true" }) })) : null] }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuGroup, { children: [_jsx(ThemeModeMenu, { ...theme }), language ? _jsx(MenuChoiceRow, { ...language }) : null, choices.map((choice) => (_jsx(AccountMenuChoiceRow, { choice: choice }, choice.label)))] }), commands.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), _jsx(DropdownMenuGroup, { children: commands.map(({ value, ...command }) => (_jsx(MenuCommandRow, { command: command, value: value }, command.label))) })] })) : null, _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuGroup, { children: [_jsx(DropdownMenuCommand, { "aria-busy": signOut.pending || undefined, closeOnClick: signOut.confirms === true, disabled: signOut.pending, icon: _jsx(LogOut, {}), onClick: () => {
34
+ const commandRows = commands.map(({ value, ...command }) => (_jsx(AccountMenuRow, { "aria-label": command.accessibleName, disabled: command.locked === true || command.disabledReason !== undefined, icon: command.icon, reason: command.locked ? command.reason : command.disabledReason, value: value, ...menuItemAction(command), children: command.label }, command.label)));
35
+ return (_jsxs(DropdownMenu, { onOpenChange: onOpenChange, children: [_jsx(DropdownMenuTrigger, { "aria-label": name, className: cn("group/account flex min-h-9 min-w-0 items-center rounded-full outline-none focus-visible:nc-focus-outline focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50", pictureOnly ? "justify-center" : "w-full pr-2 pl-2.5"), disabled: signOut.pending, children: _jsx(AccountMenuIdentity, { identity: identity, pictureOnly: pictureOnly }) }), _jsxs(DropdownMenuContent, { align: align, "aria-label": name, className: "w-72 max-w-[calc(100vw-2rem)] p-1.5", density: "comfortable", side: side, sideOffset: 6, children: [_jsxs(DropdownMenuGroup, { className: "flex min-w-0 items-center gap-2 py-1.5 pl-2", "data-slot": "account-menu-header", children: [_jsxs("span", { className: "grid min-w-0 flex-1 gap-0.5 text-left", children: [_jsx("span", { className: "truncate text-sm font-medium text-foreground", children: identity.name }), identity.notice ? _jsx("span", { className: "text-xs", children: identity.notice }) : null, identity.lines?.map((line, index) => (_jsx("span", { className: "truncate text-xs text-muted-foreground", children: line }, index)))] }), settings ? (_jsx(DropdownMenuItem, { "aria-label": settings.label, className: "text-muted-foreground", iconOnly: true, ...menuItemAction(settings), children: _jsx(Settings, { "aria-hidden": "true" }) })) : null] }), _jsx(DropdownMenuSeparator, { className: "-mx-1.5 my-1.5" }), _jsxs(DropdownMenuGroup, { children: [commandsAt === "start" ? commandRows : null, _jsx(ThemeModeMenu, { ...theme }), language ? _jsx(MenuChoiceRow, { ...language }) : null, choices.map((choice) => (_jsx(AccountMenuChoiceRow, { choice: choice }, choice.label))), commandsAt === "end" ? commandRows : null, _jsx(AccountMenuRow, { "aria-busy": signOut.pending || undefined, closeOnClick: signOut.confirms === true, disabled: signOut.pending, icon: _jsx(LogOut, {}), onClick: () => {
35
36
  if (!signOut.pending)
36
37
  signOut.onSignOut();
37
- }, variant: "destructive", children: _jsx(PendingLabel, { pending: signOut.pending, pendingLabel: signOut.pendingLabel, children: signOut.label }) }), signOut.pending ? (_jsx("span", { className: "sr-only", role: "status", children: signOut.pendingLabel })) : null, signOut.failure ? (_jsxs(FieldError, { className: "mx-3 mb-1 break-words", "data-message-code": signOut.failure.code, children: [_jsx("span", { className: "block font-medium", children: signOut.failure.title }), bodyBeyondTitle(signOut.failure) ? (_jsx("span", { className: "block", children: bodyBeyondTitle(signOut.failure) })) : null] })) : null] })] })] }));
38
+ }, children: _jsx(PendingLabel, { pending: signOut.pending, pendingLabel: signOut.pendingLabel, children: signOut.label }) }), signOut.pending ? (_jsx("span", { className: "sr-only", role: "status", children: signOut.pendingLabel })) : null, signOut.failure ? (_jsxs(FieldError, { className: "mx-2 mb-1 break-words", "data-message-code": signOut.failure.code, children: [_jsx("span", { className: "block font-medium", children: signOut.failure.title }), bodyBeyondTitle(signOut.failure) ? (_jsx("span", { className: "block", children: bodyBeyondTitle(signOut.failure) })) : null] })) : null] })] })] }));
39
+ }
40
+ function AccountMenuRow({ children, icon, reason, value, ...props }) {
41
+ return (_jsxs(DropdownMenuItem, { ...props, className: "min-h-9 gap-3 px-2 py-1.5 group-data-[density=comfortable]/menu:px-2 group-data-[density=comfortable]/menu:py-1.5 [@media(hover:hover)_and_(pointer:fine)]:min-h-9", children: [_jsxs("span", { className: "grid min-w-0 flex-1 gap-0.5", children: [_jsx("span", { className: "truncate", children: children }), reason ? _jsx("span", { className: "text-xs text-muted-foreground", children: reason }) : null] }), value === undefined ? null : " ", value === undefined ? null : (_jsx(DropdownMenuShortcut, { className: "ml-0", children: value })), _jsx("span", { "aria-hidden": "true", className: "flex shrink-0 items-center text-muted-foreground", children: icon })] }));
38
42
  }
39
43
  function AccountMenuChoiceRow({ choice }) {
40
44
  const current = choice.options.find((option) => option.value === choice.value);
41
- return (_jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { className: "gap-2.5", children: [_jsx("span", { "aria-hidden": "true", className: "flex shrink-0 items-center text-muted-foreground", children: choice.icon }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: choice.label }), current ? (_jsx(DropdownMenuShortcut, { className: "ml-0", children: current.label })) : null] }), _jsx(DropdownMenuSubContent, { children: _jsx(DropdownMenuRadioGroup, { "aria-label": choice.label, onValueChange: (next) => {
45
+ return (_jsxs(DropdownMenuSub, { children: [_jsxs(DropdownMenuSubTrigger, { className: "min-h-9 gap-3 px-2 py-1.5 group-data-[density=comfortable]/menu:px-2 group-data-[density=comfortable]/menu:py-1.5 [@media(hover:hover)_and_(pointer:fine)]:min-h-9", children: [_jsx("span", { className: "min-w-0 flex-1 truncate", children: choice.label }), current ? (_jsx(DropdownMenuShortcut, { className: "ml-0", children: current.label })) : null] }), _jsx(DropdownMenuSubContent, { children: _jsx(DropdownMenuRadioGroup, { "aria-label": choice.label, onValueChange: (next) => {
42
46
  const selected = choice.options.find((option) => option.value === next);
43
47
  if (selected)
44
48
  choice.onValueChange(selected.value);
@@ -1,20 +1,21 @@
1
- import type { ComponentProps, ReactElement, ReactNode } from "react";
2
- import { DropdownMenuContent } from "./dropdown-menu.js";
3
- import type { PageCommandAction } from "./page-actions.js";
4
- /** One command in a menu: its icon first, then its label. */
5
- export type MenuCommand = PageCommandAction & {
1
+ import type { ComponentProps, ReactElement } from "react";
2
+ import { DropdownMenuContent, type DropdownMenuCommandState } from "./dropdown-menu.js";
3
+ import type { PageCommandAction, PendingWord } from "./page-actions.js";
4
+ /**
5
+ * One command in a menu: its icon first, then its label. It is runnable, or it cannot run now and says why
6
+ * (`disabledReason`), or the person may not run it (`locked`, with its `reason`), or it is running (`pending`,
7
+ * which always comes with its `pendingLabel`, the label's -ing form: "Removing mailbox").
8
+ */
9
+ export type MenuCommand = PageCommandAction & PendingWord & {
6
10
  label: string;
7
11
  icon: ReactElement;
8
12
  /** Read instead of the label when the label alone does not name the target: "Let Sofia use Gmail". */
9
13
  accessibleName?: string | undefined;
10
14
  /** Drawn last, after the divider, in the error colour. */
11
15
  destructive?: boolean | undefined;
12
- disabled?: boolean | undefined;
13
16
  /** The value it acts on, in mono under its label: the address Copy address copies. */
14
17
  detail?: string | undefined;
15
- /** Why it cannot run now, read under its label; a disabled command keeps it visible. */
16
- reason?: ReactNode;
17
- };
18
+ } & DropdownMenuCommandState;
18
19
  /** A record's menu: whose it is, and what can be done to it. */
19
20
  export type RecordMenu = {
20
21
  /** The trigger's accessible name, from the catalogue: "More for pec@acme.it". */
@@ -38,11 +39,11 @@ export type ActionMenuProps = RecordMenu & {
38
39
  * A record's three dots: the menu of its secondary commands, headed by the record's name.
39
40
  *
40
41
  * @family Menus
41
- * @when The secondary commands of one record from a visible trigger: the row's three dots, or the page's, which comes last in the title row.
42
- * @instead For a record's main task use a visible button (Edit opens the row). For finding across everything use `CommandDialog`. For a value to choose use `Select`. For right-click use the mirror, `ActionContextMenu`.
43
- * @behaviour Ghost 36 px trigger that keeps its fill while open. The menu opens aligned to the trigger's end, 6 px below: the record's name, the commands with their icons first and the value one acts on in mono under it, then the destructive ones after a divider in the error colour. Typeahead, arrows, Escape returns focus. A disabled command stays, greyed, with its reason under it. Nothing renders with no command.
44
- * @words The trigger reads "More for {record}"; the header is the record's name. Commands are verb and noun in sentence case, "Remove mailbox", never a bare "Delete". About ten at most; rows wrap, never truncate.
45
- * @access The trigger is a ghost icon button named by `label`, `aria-expanded` while open. `role="menu"`, items `menuitem` in a group named by the record; the value a command acts on and its reason are the item's description; icons hidden.
42
+ * @when "An overflow menu triggered by a three-dot icon that reveals additional actions in a dropdown." (https://vercel.com/geist/dots-menu) "Use Menu for a discoverable trigger that opens a list of actions on a single resource (a dots menu on a row, a dropdown on a primary entity)." (https://vercel.com/geist/menu) Ours: the secondary commands of one record from a visible trigger: the row's three dots, or the page's, which comes last in the title row. A record's one main task is a visible button beside the dots; one non-destructive command that can run, alone, is drawn as a button by `RecordList` and `PageActions`, never as a menu; one that cannot run or is locked stays in the menu so its reason is read.
43
+ * @instead "For right-click or long-press on a row, use `ContextMenu`. For global commands behind `⌘K`, use `CommandMenu`. For two related primary actions, use a split button rather than burying the secondary action." (https://vercel.com/geist/menu) Ours: for a record's main task use a visible button (Edit opens the row). For finding across everything use `CommandDialog`. For a value to choose use `Select`. For right-click use the mirror, `ActionContextMenu`.
44
+ * @behaviour "Open on click, not hover; hover-open menus collide with screen readers and trackpad scrolls." (https://vercel.com/geist/menu) "Position auto-flips based on window bounds; don’t hardcode a side that clips on narrow viewports." (https://vercel.com/geist/menu) "Close on item activation, Escape, and outside-click. Don’t auto-close on a hover-out." (https://vercel.com/geist/menu) "Use `MenuItemLocked` for permission-gated actions so the lock icon and disabled state explain why the row is inert." (https://vercel.com/geist/menu) Ours: that is `locked` with its `reason`, in the same tooltip. The trigger keeps its fill while open. The menu opens 10 px under the trigger, aligned to its end: the record's name, the commands with their icons first and the value one acts on in mono under it, then the destructive ones after a divider in the error colour. A command that cannot run now takes `disabledReason`: it stays in place, 36 px like the rest, with its text muted, never dimmed, and says why in a tooltip on the row; a destructive one is muted, not red; a running one takes `pending` and `pendingLabel`. Nothing renders with no command.
45
+ * @words "Item children are Title Case `Verb + Noun` (`Rename Project`, `Duplicate Deployment`). Bare verbs like `Rename` or `Edit` are wrong outside obvious single-object context." (https://vercel.com/geist/menu) "End an item with `…` only when activating it opens a follow-up dialog (`Rename…`, `Transfer to Team…`)." (https://vercel.com/geist/menu) "Group destructive items at the bottom, separated by a divider, and keep the destructive copy as `Verb + Noun` (`Delete Project`, never bare `Delete`)." (https://vercel.com/geist/menu) "Cap a Menu around 10 items. Past that, group with `MenuSection` or move secondary actions to a settings page." (https://vercel.com/geist/menu) Ours: sentence case, "Remove mailbox", not Title Case. The trigger reads "More for {record}"; the header is the record's name. Rows wrap, never truncate.
46
+ * @access "Typeahead jumps to the next item whose label starts with the typed character; keep the visible label first so typeahead matches what the user sees." (https://vercel.com/geist/menu) "Return focus to the trigger on close so keyboard users keep their place in the row." (https://vercel.com/geist/menu) Ours: the trigger is a ghost icon button named by `label`, which is required, `aria-expanded` while open. `role="menu"`, items `menuitem` in a group named by `record`, which is required; every command requires its `icon`. The value a command acts on and its reason are the item's description; icons hidden.
46
47
  */
47
48
  export declare function ActionMenu({ label, record, commands, triggerId, open, onOpenChange, modal, side, finalFocus, }: ActionMenuProps): import("react").JSX.Element | null;
48
49
  /** The same commands on a right-click, Shift+F10 or the Menu key of the record's row. */
@@ -54,11 +55,11 @@ export type ActionContextMenuProps = RecordMenu & {
54
55
  * A record's menu opened from its row by a right-click: the mirror of its `ActionMenu`.
55
56
  *
56
57
  * @family Menus
57
- * @when A right-click or long-press convenience on a record that already has a visible menu with the same commands.
58
- * @instead For anything a person must find use the visible three dots or a button: a context menu is never the only way. For global search use `CommandDialog`.
59
- * @behaviour The dropdown's surface and rows exactly, opening at the pointer. The same commands in the same order, the same disabled reasons, destructive last after a divider. With no command the row renders alone.
60
- * @words Identical to the visible menu's, in the same order; a command reached two ways reads the same both ways.
61
- * @access The Menu key and Shift+F10 open it on the focused row. The menu is named by `label`; Escape closes it and returns focus to the row.
58
+ * @when "ContextMenu must never be the only entry point for an action. Mirror every item in a visible `Menu` trigger or row button so mouse-only and keyboard-only users have parity." (https://vercel.com/geist/context-menu) Ours: a right-click or long-press convenience on a record that already has a visible menu with the same commands.
59
+ * @instead "For a global command palette, use `CommandMenu`; for a dropdown opened from a visible trigger, use `Menu`." (https://vercel.com/geist/context-menu) Ours: for anything a person must find use the visible three dots or a button. For global search use `CommandDialog`.
60
+ * @behaviour "Bind to right-click on desktop and long-press on touch. Suppress the native browser menu only on the trigger area, not the whole page." (https://vercel.com/geist/context-menu) "Position the menu at the pointer; if it would overflow the viewport, flip horizontally then vertically before clipping." (https://vercel.com/geist/context-menu) "Close on activation, Escape, and outside-click. Don’t close on hover-out." (https://vercel.com/geist/context-menu) Ours: the dropdown's surface and rows exactly. The same commands in the same order, the same muted rows and reasons, destructive last after a divider. With no command the row renders alone.
61
+ * @words "Items follow the same rules as `Menu`: Title Case `Verb + Noun` (`Open in New Tab`, `Copy URL`, `Delete Deployment`). Bare verbs are wrong." (https://vercel.com/geist/context-menu) Ours: sentence case, "Copy address". Identical to the visible menu's, in the same order; a command reached two ways reads the same both ways.
62
+ * @access "Trigger the keyboard menu key (`Shift+F10` on Windows/Linux, the menu key, or platform equivalent) to open the same menu without right-click." (https://vercel.com/geist/context-menu) "Up/Down arrows move focus, Enter/Space activates, Escape closes and returns focus to the row." (https://vercel.com/geist/context-menu) Ours: the menu is named by `label`, which is required.
62
63
  */
63
64
  export declare function ActionContextMenu({ label, record, commands, children }: ActionContextMenuProps): import("react").JSX.Element;
64
65
  //# sourceMappingURL=action-menu.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-menu.d.ts","sourceRoot":"","sources":["../../src/components/action-menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAKrE,OAAO,EAAgB,mBAAmB,EAAuB,MAAM,4BAA4B,CAAC;AACpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,6DAA6D;AAC7D,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,sGAAsG;IACtG,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,wFAAwF;IACxF,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB,CAAC;AAEF,gEAAgE;AAChE,MAAM,MAAM,UAAU,GAAG;IACvB,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG;IACzC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,gGAAgG;IAChG,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACrD,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IACpC,gGAAgG;IAChG,UAAU,CAAC,EAAE,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC,YAAY,CAAC,CAAC;CACvE,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,IAAe,EACf,UAAU,GACX,EAAE,eAAe,sCAoBjB;AAED,yFAAyF;AACzF,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG;IAChD,wEAAwE;IACxE,QAAQ,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,sBAAsB,+BAU9F"}
1
+ {"version":3,"file":"action-menu.d.ts","sourceRoot":"","sources":["../../src/components/action-menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAK1D,OAAO,EAEL,mBAAmB,EAEnB,KAAK,wBAAwB,EAC9B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAKhF;;;;GAIG;AACH,MAAM,MAAM,WAAW,GAAG,iBAAiB,GACzC,WAAW,GAAG;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,sGAAsG;IACtG,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,0DAA0D;IAC1D,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,sFAAsF;IACtF,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,wBAAwB,CAAC;AAE/B,gEAAgE;AAChE,MAAM,MAAM,UAAU,GAAG;IACvB,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG;IACzC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,gGAAgG;IAChG,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACrD,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;IACpC,gGAAgG;IAChG,UAAU,CAAC,EAAE,cAAc,CAAC,OAAO,mBAAmB,CAAC,CAAC,YAAY,CAAC,CAAC;CACvE,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,YAAY,EACZ,KAAK,EACL,IAAe,EACf,UAAU,GACX,EAAE,eAAe,sCA4BjB;AAED,yFAAyF;AACzF,MAAM,MAAM,sBAAsB,GAAG,UAAU,GAAG;IAChD,wEAAwE;IACxE,QAAQ,EAAE,YAAY,CAAC;CACxB,CAAC;AAEF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,sBAAsB,+BAc9F"}
@@ -3,35 +3,42 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { EllipsisIcon } from "lucide-react";
4
4
  import { Button } from "./button.js";
5
5
  import { ContextMenu, ContextMenuContent, ContextMenuTrigger } from "./context-menu.js";
6
- import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "./dropdown-menu.js";
6
+ import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, } from "./dropdown-menu.js";
7
7
  import { RecordMenuItems } from "../internal/record-menu-items.js";
8
+ const MAX_COMMANDS = 10;
8
9
  /**
9
10
  * A record's three dots: the menu of its secondary commands, headed by the record's name.
10
11
  *
11
12
  * @family Menus
12
- * @when The secondary commands of one record from a visible trigger: the row's three dots, or the page's, which comes last in the title row.
13
- * @instead For a record's main task use a visible button (Edit opens the row). For finding across everything use `CommandDialog`. For a value to choose use `Select`. For right-click use the mirror, `ActionContextMenu`.
14
- * @behaviour Ghost 36 px trigger that keeps its fill while open. The menu opens aligned to the trigger's end, 6 px below: the record's name, the commands with their icons first and the value one acts on in mono under it, then the destructive ones after a divider in the error colour. Typeahead, arrows, Escape returns focus. A disabled command stays, greyed, with its reason under it. Nothing renders with no command.
15
- * @words The trigger reads "More for {record}"; the header is the record's name. Commands are verb and noun in sentence case, "Remove mailbox", never a bare "Delete". About ten at most; rows wrap, never truncate.
16
- * @access The trigger is a ghost icon button named by `label`, `aria-expanded` while open. `role="menu"`, items `menuitem` in a group named by the record; the value a command acts on and its reason are the item's description; icons hidden.
13
+ * @when "An overflow menu triggered by a three-dot icon that reveals additional actions in a dropdown." (https://vercel.com/geist/dots-menu) "Use Menu for a discoverable trigger that opens a list of actions on a single resource (a dots menu on a row, a dropdown on a primary entity)." (https://vercel.com/geist/menu) Ours: the secondary commands of one record from a visible trigger: the row's three dots, or the page's, which comes last in the title row. A record's one main task is a visible button beside the dots; one non-destructive command that can run, alone, is drawn as a button by `RecordList` and `PageActions`, never as a menu; one that cannot run or is locked stays in the menu so its reason is read.
14
+ * @instead "For right-click or long-press on a row, use `ContextMenu`. For global commands behind `⌘K`, use `CommandMenu`. For two related primary actions, use a split button rather than burying the secondary action." (https://vercel.com/geist/menu) Ours: for a record's main task use a visible button (Edit opens the row). For finding across everything use `CommandDialog`. For a value to choose use `Select`. For right-click use the mirror, `ActionContextMenu`.
15
+ * @behaviour "Open on click, not hover; hover-open menus collide with screen readers and trackpad scrolls." (https://vercel.com/geist/menu) "Position auto-flips based on window bounds; don’t hardcode a side that clips on narrow viewports." (https://vercel.com/geist/menu) "Close on item activation, Escape, and outside-click. Don’t auto-close on a hover-out." (https://vercel.com/geist/menu) "Use `MenuItemLocked` for permission-gated actions so the lock icon and disabled state explain why the row is inert." (https://vercel.com/geist/menu) Ours: that is `locked` with its `reason`, in the same tooltip. The trigger keeps its fill while open. The menu opens 10 px under the trigger, aligned to its end: the record's name, the commands with their icons first and the value one acts on in mono under it, then the destructive ones after a divider in the error colour. A command that cannot run now takes `disabledReason`: it stays in place, 36 px like the rest, with its text muted, never dimmed, and says why in a tooltip on the row; a destructive one is muted, not red; a running one takes `pending` and `pendingLabel`. Nothing renders with no command.
16
+ * @words "Item children are Title Case `Verb + Noun` (`Rename Project`, `Duplicate Deployment`). Bare verbs like `Rename` or `Edit` are wrong outside obvious single-object context." (https://vercel.com/geist/menu) "End an item with `…` only when activating it opens a follow-up dialog (`Rename…`, `Transfer to Team…`)." (https://vercel.com/geist/menu) "Group destructive items at the bottom, separated by a divider, and keep the destructive copy as `Verb + Noun` (`Delete Project`, never bare `Delete`)." (https://vercel.com/geist/menu) "Cap a Menu around 10 items. Past that, group with `MenuSection` or move secondary actions to a settings page." (https://vercel.com/geist/menu) Ours: sentence case, "Remove mailbox", not Title Case. The trigger reads "More for {record}"; the header is the record's name. Rows wrap, never truncate.
17
+ * @access "Typeahead jumps to the next item whose label starts with the typed character; keep the visible label first so typeahead matches what the user sees." (https://vercel.com/geist/menu) "Return focus to the trigger on close so keyboard users keep their place in the row." (https://vercel.com/geist/menu) Ours: the trigger is a ghost icon button named by `label`, which is required, `aria-expanded` while open. `role="menu"`, items `menuitem` in a group named by `record`, which is required; every command requires its `icon`. The value a command acts on and its reason are the item's description; icons hidden.
17
18
  */
18
19
  export function ActionMenu({ label, record, commands, triggerId, open, onOpenChange, modal, side = "bottom", finalFocus, }) {
20
+ if (typeof process !== "undefined" &&
21
+ process.env.NODE_ENV !== "production" &&
22
+ commands.length > MAX_COMMANDS) {
23
+ console.warn(`ActionMenu "${label}" has ${commands.length} commands; a menu holds ${MAX_COMMANDS} at most. Move the rest to the record's page.`);
24
+ }
19
25
  if (commands.length === 0)
20
26
  return null;
21
- return (_jsxs(DropdownMenu, { modal: modal, onOpenChange: onOpenChange ? (next) => onOpenChange(next) : undefined, open: open, children: [_jsx(DropdownMenuTrigger, { id: triggerId, "aria-label": label, render: _jsx(Button, { variant: "ghost", size: "icon" }), children: _jsx(EllipsisIcon, { "aria-hidden": "true" }) }), _jsx(DropdownMenuContent, { align: "end", finalFocus: finalFocus, side: side, children: _jsx(RecordMenuItems, { commands: commands, record: record }) })] }));
27
+ return (_jsxs(DropdownMenu, { modal: modal, onOpenChange: onOpenChange ? (next) => onOpenChange(next) : undefined, open: open, children: [_jsx(DropdownMenuTrigger, { id: triggerId, render: _jsx(Button, { variant: "ghost", size: "icon", "aria-label": label }), children: _jsx(EllipsisIcon, { "aria-hidden": "true" }) }), _jsx(DropdownMenuContent, { align: "end", finalFocus: finalFocus, side: side, children: _jsx(RecordMenuItems, { commands: commands, record: record }) })] }));
22
28
  }
23
29
  /**
24
30
  * A record's menu opened from its row by a right-click: the mirror of its `ActionMenu`.
25
31
  *
26
32
  * @family Menus
27
- * @when A right-click or long-press convenience on a record that already has a visible menu with the same commands.
28
- * @instead For anything a person must find use the visible three dots or a button: a context menu is never the only way. For global search use `CommandDialog`.
29
- * @behaviour The dropdown's surface and rows exactly, opening at the pointer. The same commands in the same order, the same disabled reasons, destructive last after a divider. With no command the row renders alone.
30
- * @words Identical to the visible menu's, in the same order; a command reached two ways reads the same both ways.
31
- * @access The Menu key and Shift+F10 open it on the focused row. The menu is named by `label`; Escape closes it and returns focus to the row.
33
+ * @when "ContextMenu must never be the only entry point for an action. Mirror every item in a visible `Menu` trigger or row button so mouse-only and keyboard-only users have parity." (https://vercel.com/geist/context-menu) Ours: a right-click or long-press convenience on a record that already has a visible menu with the same commands.
34
+ * @instead "For a global command palette, use `CommandMenu`; for a dropdown opened from a visible trigger, use `Menu`." (https://vercel.com/geist/context-menu) Ours: for anything a person must find use the visible three dots or a button. For global search use `CommandDialog`.
35
+ * @behaviour "Bind to right-click on desktop and long-press on touch. Suppress the native browser menu only on the trigger area, not the whole page." (https://vercel.com/geist/context-menu) "Position the menu at the pointer; if it would overflow the viewport, flip horizontally then vertically before clipping." (https://vercel.com/geist/context-menu) "Close on activation, Escape, and outside-click. Don’t close on hover-out." (https://vercel.com/geist/context-menu) Ours: the dropdown's surface and rows exactly. The same commands in the same order, the same muted rows and reasons, destructive last after a divider. With no command the row renders alone.
36
+ * @words "Items follow the same rules as `Menu`: Title Case `Verb + Noun` (`Open in New Tab`, `Copy URL`, `Delete Deployment`). Bare verbs are wrong." (https://vercel.com/geist/context-menu) Ours: sentence case, "Copy address". Identical to the visible menu's, in the same order; a command reached two ways reads the same both ways.
37
+ * @access "Trigger the keyboard menu key (`Shift+F10` on Windows/Linux, the menu key, or platform equivalent) to open the same menu without right-click." (https://vercel.com/geist/context-menu) "Up/Down arrows move focus, Enter/Space activates, Escape closes and returns focus to the row." (https://vercel.com/geist/context-menu) Ours: the menu is named by `label`, which is required.
32
38
  */
33
39
  export function ActionContextMenu({ label, record, commands, children }) {
34
- if (commands.length === 0)
35
- return children;
36
- return (_jsxs(ContextMenu, { children: [_jsx(ContextMenuTrigger, { render: children }), _jsx(ContextMenuContent, { "aria-label": label, children: _jsx(RecordMenuItems, { commands: commands, record: record }) })] }));
40
+ const none = commands.length === 0;
41
+ // The row stays one element whether or not it has commands, so a menu that appears or goes
42
+ // never remounts the row; with none the browser keeps its own menu and the row its selection.
43
+ return (_jsxs(ContextMenu, { disabled: none, children: [_jsx(ContextMenuTrigger, { className: none ? "select-auto" : undefined, render: children }), none ? null : (_jsx(ContextMenuContent, { "aria-label": label, children: _jsx(RecordMenuItems, { commands: commands, record: record }) }))] }));
37
44
  }
@@ -1,26 +1,30 @@
1
1
  import type { ReactNode } from "react";
2
- interface ActionStatusProps {
2
+ import { type TextButtonProps } from "./button.js";
3
+ type ActionStatusProps = Omit<TextButtonProps, "children" | "loading" | "loadingLabel" | "prefix" | "suffix"> & {
3
4
  state: "done" | "idle" | "saving";
4
5
  idle: string;
5
6
  busy: string;
6
7
  done: string;
7
8
  idleIcon?: ReactNode;
8
- }
9
+ };
9
10
  /**
10
- * A control's three words on one action: what it does, what it is doing, what it did.
11
+ * A button's three words on one action: what it does, what it is doing, what it did.
11
12
  *
12
13
  * @family Status
13
- * @when A control that reports its own action: what it does, what it is doing, what it did. Waits
14
+ * @when A button that reports its own action: what it does, what it is doing, what it did. Waits
14
15
  * under about a second.
15
16
  * @instead The record's resulting state is a `StatusBadge`. A wait past a second adds one waiting
16
- * line beside the work. An Agent's work is her orb.
17
- * @behaviour Saving keeps the idle icon, the size and the place; only the word changes. The caller
18
- * sets `disabled` and `aria-busy`. Done shows the check.
17
+ * line beside the work. An Agent's work is her orb. A button with no done word is a `Button` with
18
+ * `loading`.
19
+ * @behaviour Takes the props of a text `Button`. Saving is the button's `loading`: the idle icon, the
20
+ * size and the place stay, only the word changes, a second press is ignored and focus stays. Done
21
+ * swaps the icon for the check.
19
22
  * @words Verb and noun idle (*Save changes*), the verb in progress (*Saving*), the result
20
23
  * (*Saved*). No ellipsis. Italian: *Salva modifiche*, *Salvataggio*, *Salvato*.
21
- * @access The button's name is the current word. The result is announced once in a `role="status"`
22
- * region; a failure as an alert.
24
+ * @access The button's name is the current word, and it is `aria-busy` while saving. It renders no
25
+ * status region: the caller's `role="status"` region announces the result once and a failure as an
26
+ * alert.
23
27
  */
24
- declare function ActionStatus({ state, idle, busy, done, idleIcon }: ActionStatusProps): import("react").JSX.Element;
28
+ declare function ActionStatus({ state, idle, busy, done, idleIcon, ...props }: ActionStatusProps): import("react").JSX.Element;
25
29
  export { ActionStatus };
26
30
  //# sourceMappingURL=action-status.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"action-status.d.ts","sourceRoot":"","sources":["../../src/components/action-status.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,UAAU,iBAAiB;IACzB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AACD;;;;;;;;;;;;;;GAcG;AACH,iBAAS,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAe,EAAE,EAAE,iBAAiB,+BAOpF;AACD,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"action-status.d.ts","sourceRoot":"","sources":["../../src/components/action-status.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,EAAU,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEnE,KAAK,iBAAiB,GAAG,IAAI,CAC3B,eAAe,EACf,UAAU,GAAG,SAAS,GAAG,cAAc,GAAG,QAAQ,GAAG,QAAQ,CAC9D,GAAG;IACF,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,iBAAS,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,iBAAiB,+BAWvF;AACD,OAAO,EAAE,YAAY,EAAE,CAAC"}