@nadicodeai/ui 12.1.102 → 12.1.104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (562) hide show
  1. package/dist/components/accordion.d.ts +38 -12
  2. package/dist/components/accordion.d.ts.map +1 -1
  3. package/dist/components/accordion.js +36 -15
  4. package/dist/components/account-menu.js +2 -2
  5. package/dist/components/action-menu.d.ts +20 -19
  6. package/dist/components/action-menu.d.ts.map +1 -1
  7. package/dist/components/action-menu.js +22 -15
  8. package/dist/components/action-status.d.ts +14 -10
  9. package/dist/components/action-status.d.ts.map +1 -1
  10. package/dist/components/action-status.js +14 -10
  11. package/dist/components/activity-calendar.d.ts +3 -1
  12. package/dist/components/activity-calendar.d.ts.map +1 -1
  13. package/dist/components/activity-calendar.js +16 -2
  14. package/dist/components/activity-feed.d.ts +2 -2
  15. package/dist/components/activity-feed.d.ts.map +1 -1
  16. package/dist/components/activity-feed.js +14 -5
  17. package/dist/components/agent-card.d.ts +11 -5
  18. package/dist/components/agent-card.d.ts.map +1 -1
  19. package/dist/components/agent-card.js +13 -7
  20. package/dist/components/agent-list-row.js +1 -1
  21. package/dist/components/agent-orb-appearance.d.ts +7 -1
  22. package/dist/components/agent-orb-appearance.d.ts.map +1 -1
  23. package/dist/components/agent-orb-appearance.js +26 -0
  24. package/dist/components/agent-profile.d.ts +8 -7
  25. package/dist/components/agent-profile.d.ts.map +1 -1
  26. package/dist/components/agent-profile.js +6 -6
  27. package/dist/components/alert-dialog.d.ts +25 -16
  28. package/dist/components/alert-dialog.d.ts.map +1 -1
  29. package/dist/components/alert-dialog.js +30 -18
  30. package/dist/components/alert.d.ts +1 -1
  31. package/dist/components/avatar.d.ts +83 -17
  32. package/dist/components/avatar.d.ts.map +1 -1
  33. package/dist/components/avatar.js +89 -23
  34. package/dist/components/badge.d.ts +59 -8
  35. package/dist/components/badge.d.ts.map +1 -1
  36. package/dist/components/badge.js +57 -14
  37. package/dist/components/breadcrumb.d.ts +18 -7
  38. package/dist/components/breadcrumb.d.ts.map +1 -1
  39. package/dist/components/breadcrumb.js +37 -13
  40. package/dist/components/button-group.d.ts +12 -15
  41. package/dist/components/button-group.d.ts.map +1 -1
  42. package/dist/components/button-group.js +13 -17
  43. package/dist/components/button.d.ts +126 -23
  44. package/dist/components/button.d.ts.map +1 -1
  45. package/dist/components/button.js +164 -39
  46. package/dist/components/calendar.d.ts +26 -15
  47. package/dist/components/calendar.d.ts.map +1 -1
  48. package/dist/components/calendar.js +60 -46
  49. package/dist/components/card-row.d.ts +13 -5
  50. package/dist/components/card-row.d.ts.map +1 -1
  51. package/dist/components/card-row.js +24 -10
  52. package/dist/components/card.d.ts +6 -12
  53. package/dist/components/card.d.ts.map +1 -1
  54. package/dist/components/card.js +11 -16
  55. package/dist/components/carousel.d.ts +3 -3
  56. package/dist/components/carousel.d.ts.map +1 -1
  57. package/dist/components/carousel.js +7 -7
  58. package/dist/components/catalog-drawer.d.ts +7 -7
  59. package/dist/components/catalog-drawer.d.ts.map +1 -1
  60. package/dist/components/catalog-drawer.js +6 -6
  61. package/dist/components/chart-area-stacked.d.ts +1 -1
  62. package/dist/components/chart-area-stacked.d.ts.map +1 -1
  63. package/dist/components/chart-area-stacked.js +4 -4
  64. package/dist/components/chart-axis.d.ts +14 -1
  65. package/dist/components/chart-axis.d.ts.map +1 -1
  66. package/dist/components/chart-axis.js +11 -1
  67. package/dist/components/chart-bar-horizontal.d.ts +2 -2
  68. package/dist/components/chart-bar-horizontal.d.ts.map +1 -1
  69. package/dist/components/chart-bar-horizontal.js +14 -5
  70. package/dist/components/chart-bar-multiple.d.ts +1 -1
  71. package/dist/components/chart-bar-multiple.d.ts.map +1 -1
  72. package/dist/components/chart-bar-multiple.js +3 -3
  73. package/dist/components/chart-bar-stacked.d.ts +1 -1
  74. package/dist/components/chart-bar-stacked.d.ts.map +1 -1
  75. package/dist/components/chart-bar-stacked.js +3 -3
  76. package/dist/components/chart-card.d.ts +17 -6
  77. package/dist/components/chart-card.d.ts.map +1 -1
  78. package/dist/components/chart-card.js +11 -4
  79. package/dist/components/chart-date-range-control.d.ts +18 -9
  80. package/dist/components/chart-date-range-control.d.ts.map +1 -1
  81. package/dist/components/chart-date-range-control.js +43 -47
  82. package/dist/components/chart-sparkline.d.ts +4 -3
  83. package/dist/components/chart-sparkline.d.ts.map +1 -1
  84. package/dist/components/chart-sparkline.js +6 -5
  85. package/dist/components/check-counts.d.ts +44 -0
  86. package/dist/components/check-counts.d.ts.map +1 -0
  87. package/dist/components/check-counts.js +51 -0
  88. package/dist/components/checkbox.d.ts +39 -11
  89. package/dist/components/checkbox.d.ts.map +1 -1
  90. package/dist/components/checkbox.js +38 -11
  91. package/dist/components/choicebox.d.ts +96 -0
  92. package/dist/components/choicebox.d.ts.map +1 -0
  93. package/dist/components/choicebox.js +113 -0
  94. package/dist/components/clearable-input.d.ts +57 -0
  95. package/dist/components/clearable-input.d.ts.map +1 -0
  96. package/dist/components/clearable-input.js +58 -0
  97. package/dist/components/code-block.d.ts +77 -17
  98. package/dist/components/code-block.d.ts.map +1 -1
  99. package/dist/components/code-block.js +85 -15
  100. package/dist/components/collapsible.d.ts +27 -10
  101. package/dist/components/collapsible.d.ts.map +1 -1
  102. package/dist/components/collapsible.js +24 -9
  103. package/dist/components/collection-filters.d.ts +3 -1
  104. package/dist/components/collection-filters.d.ts.map +1 -1
  105. package/dist/components/collection-filters.js +7 -9
  106. package/dist/components/collection-page.d.ts +31 -10
  107. package/dist/components/collection-page.d.ts.map +1 -1
  108. package/dist/components/collection-page.js +14 -13
  109. package/dist/components/collection-search.d.ts +32 -10
  110. package/dist/components/collection-search.d.ts.map +1 -1
  111. package/dist/components/collection-search.js +24 -13
  112. package/dist/components/collection-sort.d.ts.map +1 -1
  113. package/dist/components/collection-sort.js +2 -2
  114. package/dist/components/collection-toolbar.d.ts +5 -2
  115. package/dist/components/collection-toolbar.d.ts.map +1 -1
  116. package/dist/components/collection-toolbar.js +7 -4
  117. package/dist/components/combobox.d.ts +97 -22
  118. package/dist/components/combobox.d.ts.map +1 -1
  119. package/dist/components/combobox.js +80 -28
  120. package/dist/components/command.d.ts +34 -21
  121. package/dist/components/command.d.ts.map +1 -1
  122. package/dist/components/command.js +33 -25
  123. package/dist/components/confirm-dialog.d.ts +23 -6
  124. package/dist/components/confirm-dialog.d.ts.map +1 -1
  125. package/dist/components/confirm-dialog.js +32 -13
  126. package/dist/components/context-menu.d.ts +14 -10
  127. package/dist/components/context-menu.d.ts.map +1 -1
  128. package/dist/components/context-menu.js +17 -12
  129. package/dist/components/copy-button.d.ts +5 -2
  130. package/dist/components/copy-button.d.ts.map +1 -1
  131. package/dist/components/copy-button.js +16 -8
  132. package/dist/components/data-table.d.ts +120 -54
  133. package/dist/components/data-table.d.ts.map +1 -1
  134. package/dist/components/data-table.js +163 -92
  135. package/dist/components/desktop-shell.d.ts +4 -2
  136. package/dist/components/desktop-shell.d.ts.map +1 -1
  137. package/dist/components/desktop-shell.js +3 -3
  138. package/dist/components/dialog.d.ts +63 -24
  139. package/dist/components/dialog.d.ts.map +1 -1
  140. package/dist/components/dialog.js +52 -31
  141. package/dist/components/disclosure-row.d.ts +1 -2
  142. package/dist/components/disclosure-row.d.ts.map +1 -1
  143. package/dist/components/disclosure-row.js +1 -2
  144. package/dist/components/disclosure.d.ts +1 -1
  145. package/dist/components/disclosure.js +1 -1
  146. package/dist/components/drawer.d.ts +33 -12
  147. package/dist/components/drawer.d.ts.map +1 -1
  148. package/dist/components/drawer.js +47 -35
  149. package/dist/components/dropdown-menu.d.ts +59 -14
  150. package/dist/components/dropdown-menu.d.ts.map +1 -1
  151. package/dist/components/dropdown-menu.js +58 -26
  152. package/dist/components/empty-state.d.ts +35 -12
  153. package/dist/components/empty-state.d.ts.map +1 -1
  154. package/dist/components/empty-state.js +35 -17
  155. package/dist/components/entry-scene.d.ts +4 -4
  156. package/dist/components/entry-scene.d.ts.map +1 -1
  157. package/dist/components/entry-scene.js +2 -2
  158. package/dist/components/field.d.ts +44 -14
  159. package/dist/components/field.d.ts.map +1 -1
  160. package/dist/components/field.js +49 -20
  161. package/dist/components/file-diff.d.ts.map +1 -1
  162. package/dist/components/file-diff.js +3 -4
  163. package/dist/components/form-dialog.d.ts +7 -7
  164. package/dist/components/form-dialog.d.ts.map +1 -1
  165. package/dist/components/form-dialog.js +13 -11
  166. package/dist/components/form-drawer.d.ts +10 -7
  167. package/dist/components/form-drawer.d.ts.map +1 -1
  168. package/dist/components/form-drawer.js +11 -10
  169. package/dist/components/gauge.d.ts +64 -0
  170. package/dist/components/gauge.d.ts.map +1 -0
  171. package/dist/components/gauge.js +73 -0
  172. package/dist/components/hover-card.d.ts +72 -14
  173. package/dist/components/hover-card.d.ts.map +1 -1
  174. package/dist/components/hover-card.js +51 -17
  175. package/dist/components/identity-mark.d.ts +8 -1
  176. package/dist/components/identity-mark.d.ts.map +1 -1
  177. package/dist/components/identity-mark.js +31 -5
  178. package/dist/components/input-group.d.ts +44 -21
  179. package/dist/components/input-group.d.ts.map +1 -1
  180. package/dist/components/input-group.js +74 -27
  181. package/dist/components/input.d.ts +64 -12
  182. package/dist/components/input.d.ts.map +1 -1
  183. package/dist/components/input.js +51 -15
  184. package/dist/components/item.d.ts +37 -15
  185. package/dist/components/item.d.ts.map +1 -1
  186. package/dist/components/item.js +41 -22
  187. package/dist/components/kbd.d.ts +49 -13
  188. package/dist/components/kbd.d.ts.map +1 -1
  189. package/dist/components/kbd.js +115 -16
  190. package/dist/components/kpi-card.d.ts +12 -4
  191. package/dist/components/kpi-card.d.ts.map +1 -1
  192. package/dist/components/kpi-card.js +13 -4
  193. package/dist/components/label.d.ts +17 -10
  194. package/dist/components/label.d.ts.map +1 -1
  195. package/dist/components/label.js +18 -11
  196. package/dist/components/library-shelf.d.ts +6 -6
  197. package/dist/components/library-shelf.d.ts.map +1 -1
  198. package/dist/components/library-shelf.js +5 -5
  199. package/dist/components/load-more-button.d.ts +35 -0
  200. package/dist/components/load-more-button.d.ts.map +1 -0
  201. package/dist/components/load-more-button.js +26 -0
  202. package/dist/components/message-notice.d.ts +8 -13
  203. package/dist/components/message-notice.d.ts.map +1 -1
  204. package/dist/components/message-notice.js +25 -22
  205. package/dist/components/middle-truncate.d.ts +33 -0
  206. package/dist/components/middle-truncate.d.ts.map +1 -0
  207. package/dist/components/middle-truncate.js +72 -0
  208. package/dist/components/multi-select.d.ts +94 -0
  209. package/dist/components/multi-select.d.ts.map +1 -0
  210. package/dist/components/multi-select.js +132 -0
  211. package/dist/components/native-select.d.ts +37 -13
  212. package/dist/components/native-select.d.ts.map +1 -1
  213. package/dist/components/native-select.js +27 -11
  214. package/dist/components/notice-banner.d.ts +17 -10
  215. package/dist/components/notice-banner.d.ts.map +1 -1
  216. package/dist/components/notice-banner.js +12 -11
  217. package/dist/components/numbered-steps.d.ts +10 -4
  218. package/dist/components/numbered-steps.d.ts.map +1 -1
  219. package/dist/components/numbered-steps.js +9 -7
  220. package/dist/components/object-page.d.ts +40 -14
  221. package/dist/components/object-page.d.ts.map +1 -1
  222. package/dist/components/object-page.js +12 -10
  223. package/dist/components/object-workspace.d.ts +29 -10
  224. package/dist/components/object-workspace.d.ts.map +1 -1
  225. package/dist/components/object-workspace.js +18 -8
  226. package/dist/components/overview-page.d.ts +2 -2
  227. package/dist/components/overview-page.d.ts.map +1 -1
  228. package/dist/components/overview-page.js +8 -7
  229. package/dist/components/page-actions.d.ts +28 -8
  230. package/dist/components/page-actions.d.ts.map +1 -1
  231. package/dist/components/page-actions.js +22 -25
  232. package/dist/components/page-header.d.ts +11 -4
  233. package/dist/components/page-header.d.ts.map +1 -1
  234. package/dist/components/page-header.js +10 -5
  235. package/dist/components/pending-label.d.ts +6 -5
  236. package/dist/components/pending-label.d.ts.map +1 -1
  237. package/dist/components/pending-label.js +14 -6
  238. package/dist/components/picture-label.d.ts +2 -2
  239. package/dist/components/picture-label.d.ts.map +1 -1
  240. package/dist/components/picture-label.js +3 -3
  241. package/dist/components/portal-sidebar-frame.d.ts +9 -21
  242. package/dist/components/portal-sidebar-frame.d.ts.map +1 -1
  243. package/dist/components/portal-sidebar-frame.js +13 -27
  244. package/dist/components/progress-checklist.d.ts +46 -0
  245. package/dist/components/progress-checklist.d.ts.map +1 -0
  246. package/dist/components/progress-checklist.js +46 -0
  247. package/dist/components/progress.d.ts +48 -8
  248. package/dist/components/progress.d.ts.map +1 -1
  249. package/dist/components/progress.js +92 -16
  250. package/dist/components/prose.d.ts +19 -0
  251. package/dist/components/prose.d.ts.map +1 -0
  252. package/dist/components/prose.js +29 -0
  253. package/dist/components/radio-group.d.ts +51 -12
  254. package/dist/components/radio-group.d.ts.map +1 -1
  255. package/dist/components/radio-group.js +42 -12
  256. package/dist/components/reading-column.js +1 -1
  257. package/dist/components/record-identity.d.ts +6 -5
  258. package/dist/components/record-identity.d.ts.map +1 -1
  259. package/dist/components/record-identity.js +12 -3
  260. package/dist/components/record-list.d.ts +117 -27
  261. package/dist/components/record-list.d.ts.map +1 -1
  262. package/dist/components/record-list.js +185 -55
  263. package/dist/components/record-time.d.ts +20 -7
  264. package/dist/components/record-time.d.ts.map +1 -1
  265. package/dist/components/record-time.js +38 -19
  266. package/dist/components/resizable.d.ts +7 -5
  267. package/dist/components/resizable.d.ts.map +1 -1
  268. package/dist/components/resizable.js +6 -6
  269. package/dist/components/scope-switcher.d.ts +2 -0
  270. package/dist/components/scope-switcher.d.ts.map +1 -1
  271. package/dist/components/scope-switcher.js +2 -2
  272. package/dist/components/scroll-area.d.ts +47 -11
  273. package/dist/components/scroll-area.d.ts.map +1 -1
  274. package/dist/components/scroll-area.js +72 -14
  275. package/dist/components/segmented-control.d.ts +82 -0
  276. package/dist/components/segmented-control.d.ts.map +1 -0
  277. package/dist/components/segmented-control.js +90 -0
  278. package/dist/components/select.d.ts +55 -15
  279. package/dist/components/select.d.ts.map +1 -1
  280. package/dist/components/select.js +62 -19
  281. package/dist/components/separator.d.ts +12 -5
  282. package/dist/components/separator.d.ts.map +1 -1
  283. package/dist/components/separator.js +11 -6
  284. package/dist/components/settings-facts.d.ts +34 -14
  285. package/dist/components/settings-facts.d.ts.map +1 -1
  286. package/dist/components/settings-facts.js +21 -12
  287. package/dist/components/settings-page.d.ts +4 -4
  288. package/dist/components/settings-page.js +5 -5
  289. package/dist/components/settings-section.d.ts +160 -34
  290. package/dist/components/settings-section.d.ts.map +1 -1
  291. package/dist/components/settings-section.js +92 -39
  292. package/dist/components/sheet.d.ts +47 -16
  293. package/dist/components/sheet.d.ts.map +1 -1
  294. package/dist/components/sheet.js +40 -19
  295. package/dist/components/sidebar-sections.d.ts +16 -12
  296. package/dist/components/sidebar-sections.d.ts.map +1 -1
  297. package/dist/components/sidebar-sections.js +30 -15
  298. package/dist/components/sidebar.d.ts +117 -21
  299. package/dist/components/sidebar.d.ts.map +1 -1
  300. package/dist/components/sidebar.js +180 -55
  301. package/dist/components/skeleton.d.ts +54 -8
  302. package/dist/components/skeleton.d.ts.map +1 -1
  303. package/dist/components/skeleton.js +44 -9
  304. package/dist/components/slider.d.ts +53 -11
  305. package/dist/components/slider.d.ts.map +1 -1
  306. package/dist/components/slider.js +71 -17
  307. package/dist/components/snippet.d.ts +57 -0
  308. package/dist/components/snippet.d.ts.map +1 -0
  309. package/dist/components/snippet.js +60 -0
  310. package/dist/components/sonner.d.ts +13 -14
  311. package/dist/components/sonner.d.ts.map +1 -1
  312. package/dist/components/sonner.js +25 -22
  313. package/dist/components/status-badge.d.ts +37 -11
  314. package/dist/components/status-badge.d.ts.map +1 -1
  315. package/dist/components/status-badge.js +63 -15
  316. package/dist/components/status-dot.d.ts +42 -11
  317. package/dist/components/status-dot.d.ts.map +1 -1
  318. package/dist/components/status-dot.js +40 -11
  319. package/dist/components/switch.d.ts +43 -12
  320. package/dist/components/switch.d.ts.map +1 -1
  321. package/dist/components/switch.js +42 -12
  322. package/dist/components/table-card.d.ts +21 -12
  323. package/dist/components/table-card.d.ts.map +1 -1
  324. package/dist/components/table-card.js +17 -9
  325. package/dist/components/table-layouts.d.ts +40 -8
  326. package/dist/components/table-layouts.d.ts.map +1 -1
  327. package/dist/components/table-layouts.js +52 -8
  328. package/dist/components/table-value.d.ts +4 -3
  329. package/dist/components/table-value.d.ts.map +1 -1
  330. package/dist/components/table-value.js +6 -5
  331. package/dist/components/table.d.ts +62 -25
  332. package/dist/components/table.d.ts.map +1 -1
  333. package/dist/components/table.js +62 -26
  334. package/dist/components/tabs.d.ts +86 -17
  335. package/dist/components/tabs.d.ts.map +1 -1
  336. package/dist/components/tabs.js +93 -22
  337. package/dist/components/text-link.d.ts +4 -1
  338. package/dist/components/text-link.d.ts.map +1 -1
  339. package/dist/components/text-link.js +4 -1
  340. package/dist/components/text-with-copy-button.d.ts +30 -0
  341. package/dist/components/text-with-copy-button.d.ts.map +1 -0
  342. package/dist/components/text-with-copy-button.js +32 -0
  343. package/dist/components/textarea.d.ts +40 -10
  344. package/dist/components/textarea.d.ts.map +1 -1
  345. package/dist/components/textarea.js +50 -11
  346. package/dist/components/theme-mode-switcher.d.ts +18 -1
  347. package/dist/components/theme-mode-switcher.d.ts.map +1 -1
  348. package/dist/components/theme-mode-switcher.js +20 -2
  349. package/dist/components/toggle-group.d.ts +28 -8
  350. package/dist/components/toggle-group.d.ts.map +1 -1
  351. package/dist/components/toggle-group.js +12 -6
  352. package/dist/components/toggle.d.ts +6 -3
  353. package/dist/components/toggle.d.ts.map +1 -1
  354. package/dist/components/toggle.js +10 -7
  355. package/dist/components/tooltip.d.ts +43 -12
  356. package/dist/components/tooltip.d.ts.map +1 -1
  357. package/dist/components/tooltip.js +45 -16
  358. package/dist/components/trend-badge.js +1 -1
  359. package/dist/components/update-card.js +1 -1
  360. package/dist/eslint/index.js +82 -0
  361. package/dist/eslint/rules/badge-is-static-label.js +93 -0
  362. package/dist/eslint/rules/button-icon-slot.js +102 -0
  363. package/dist/eslint/rules/button-link-for-navigation.js +146 -0
  364. package/dist/eslint/rules/button-no-aria-label-with-text.js +75 -0
  365. package/dist/eslint/rules/button-type-roles-only-in-buttons.js +83 -0
  366. package/dist/eslint/rules/choice-control-has-a-name.js +98 -0
  367. package/dist/eslint/rules/choice-group-in-fieldset.js +86 -0
  368. package/dist/eslint/rules/command-shortcut-single-owner.js +118 -0
  369. package/dist/eslint/rules/confirm-dialog-words.js +63 -0
  370. package/dist/eslint/rules/data-table-one-unsized-column.js +96 -0
  371. package/dist/eslint/rules/destructive-action-placement.js +69 -0
  372. package/dist/eslint/rules/disabled-choice-says-why.js +71 -0
  373. package/dist/eslint/rules/ellipsis-opens-a-dialog.js +110 -0
  374. package/dist/eslint/rules/input-group-owners.js +155 -0
  375. package/dist/eslint/rules/kbd-children-no-modifier-text.js +128 -0
  376. package/dist/eslint/rules/literal-text.js +41 -0
  377. package/dist/eslint/rules/middle-truncate-placement.js +69 -0
  378. package/dist/eslint/rules/no-bare-button-label.js +55 -0
  379. package/dist/eslint/rules/no-control-in-read-only-surface.js +106 -0
  380. package/dist/eslint/rules/no-hand-built-busy.js +104 -0
  381. package/dist/eslint/rules/no-hand-built-theme-picker.js +144 -0
  382. package/dist/eslint/rules/no-hand-built-tile.js +41 -0
  383. package/dist/eslint/rules/no-hand-formatted-date.js +87 -0
  384. package/dist/eslint/rules/no-hand-stacked-avatars.js +67 -0
  385. package/dist/eslint/rules/no-nested-collapse.js +60 -0
  386. package/dist/eslint/rules/no-search-in-form.js +47 -0
  387. package/dist/eslint/rules/no-shadcn-appearance-override.js +2 -16
  388. package/dist/eslint/rules/no-shell-prompt-in-snippet.js +74 -0
  389. package/dist/eslint/rules/no-stock-error-words.js +56 -0
  390. package/dist/eslint/rules/no-tooltip-around-labelled-field.js +72 -0
  391. package/dist/eslint/rules/no-weight-class-on-strong-in-type-role.js +57 -0
  392. package/dist/eslint/rules/one-submenu-level.js +43 -0
  393. package/dist/eslint/rules/one-toast-per-flow.js +91 -0
  394. package/dist/eslint/rules/option-count.js +167 -0
  395. package/dist/eslint/rules/page-command-link-not-render.js +43 -0
  396. package/dist/eslint/rules/progress-needs-name.js +57 -0
  397. package/dist/eslint/rules/settings-limit-in-footer.js +94 -0
  398. package/dist/eslint/rules/skeleton-in-region.js +80 -0
  399. package/dist/eslint/rules/sortable-heading-uses-sort.js +79 -0
  400. package/dist/eslint/rules/table-cell-inset-owner.js +107 -0
  401. package/dist/eslint/rules/tabs-selection-is-controlled.js +47 -0
  402. package/dist/eslint/rules/tooltip-only-arrow.js +38 -0
  403. package/dist/eslint/rules/tooltip-trigger-accessible-name.js +114 -0
  404. package/dist/eslint/strict-design-system.js +21 -7
  405. package/dist/index.d.ts +13 -13
  406. package/dist/index.d.ts.map +1 -1
  407. package/dist/index.js +12 -13
  408. package/dist/internal/assistant-ui/attachment.d.ts.map +1 -1
  409. package/dist/internal/assistant-ui/attachment.js +2 -2
  410. package/dist/internal/assistant-ui/reasoning.d.ts +1 -1
  411. package/dist/internal/assistant-ui/reasoning.d.ts.map +1 -1
  412. package/dist/internal/assistant-ui/tool-fallback.js +1 -1
  413. package/dist/internal/assistant-ui/tool-group.d.ts +1 -1
  414. package/dist/internal/assistant-ui/tool-group.d.ts.map +1 -1
  415. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts +2 -3
  416. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts.map +1 -1
  417. package/dist/internal/assistant-ui/tooltip-icon-button.js +1 -1
  418. package/dist/internal/catalog-list.js +2 -2
  419. package/dist/internal/collection-note.d.ts +23 -0
  420. package/dist/internal/collection-note.d.ts.map +1 -0
  421. package/dist/internal/collection-note.js +17 -0
  422. package/dist/internal/collection-rail.d.ts +57 -0
  423. package/dist/internal/collection-rail.d.ts.map +1 -0
  424. package/dist/internal/collection-rail.js +33 -0
  425. package/dist/internal/company-logo.d.ts +18 -0
  426. package/dist/internal/company-logo.d.ts.map +1 -0
  427. package/dist/internal/company-logo.js +14 -0
  428. package/dist/internal/control-name.d.ts +12 -0
  429. package/dist/internal/control-name.d.ts.map +1 -0
  430. package/dist/internal/control-name.js +1 -0
  431. package/dist/internal/diff-line.d.ts +9 -0
  432. package/dist/internal/diff-line.d.ts.map +1 -0
  433. package/dist/internal/diff-line.js +8 -0
  434. package/dist/internal/empty.d.ts +8 -4
  435. package/dist/internal/empty.d.ts.map +1 -1
  436. package/dist/internal/empty.js +14 -8
  437. package/dist/internal/field-frame.d.ts +33 -0
  438. package/dist/internal/field-frame.d.ts.map +1 -0
  439. package/dist/internal/field-frame.js +20 -0
  440. package/dist/internal/final-focus.d.ts +8 -0
  441. package/dist/internal/final-focus.d.ts.map +1 -0
  442. package/dist/internal/final-focus.js +10 -0
  443. package/dist/internal/footer-strip.d.ts.map +1 -1
  444. package/dist/internal/footer-strip.js +3 -1
  445. package/dist/internal/form-submit.d.ts +9 -5
  446. package/dist/internal/form-submit.d.ts.map +1 -1
  447. package/dist/internal/form-submit.js +31 -2
  448. package/dist/internal/input-box.d.ts +26 -0
  449. package/dist/internal/input-box.d.ts.map +1 -0
  450. package/dist/internal/input-box.js +59 -0
  451. package/dist/internal/menu-surface.d.ts +10 -3
  452. package/dist/internal/menu-surface.d.ts.map +1 -1
  453. package/dist/internal/menu-surface.js +10 -3
  454. package/dist/internal/notice.d.ts +25 -0
  455. package/dist/internal/notice.d.ts.map +1 -0
  456. package/dist/internal/notice.js +33 -0
  457. package/dist/internal/overlay-stem.d.ts +5 -0
  458. package/dist/internal/overlay-stem.d.ts.map +1 -0
  459. package/dist/internal/overlay-stem.js +7 -0
  460. package/dist/internal/phone-sheet.d.ts +4 -0
  461. package/dist/internal/phone-sheet.d.ts.map +1 -0
  462. package/dist/internal/phone-sheet.js +2 -0
  463. package/dist/internal/present-content.d.ts +3 -0
  464. package/dist/internal/present-content.d.ts.map +1 -0
  465. package/dist/internal/present-content.js +1 -0
  466. package/dist/internal/record-menu-items.d.ts +4 -3
  467. package/dist/internal/record-menu-items.d.ts.map +1 -1
  468. package/dist/internal/record-menu-items.js +21 -6
  469. package/dist/internal/settings-save.d.ts +9 -2
  470. package/dist/internal/settings-save.d.ts.map +1 -1
  471. package/dist/internal/settings-save.js +19 -6
  472. package/dist/internal/table-compact-line.d.ts +38 -0
  473. package/dist/internal/table-compact-line.d.ts.map +1 -0
  474. package/dist/internal/table-compact-line.js +35 -0
  475. package/dist/internal/title-when-cut.d.ts +8 -0
  476. package/dist/internal/title-when-cut.d.ts.map +1 -0
  477. package/dist/internal/title-when-cut.js +22 -0
  478. package/dist/internal/unsaved-guard.d.ts +18 -0
  479. package/dist/internal/unsaved-guard.d.ts.map +1 -0
  480. package/dist/internal/unsaved-guard.js +31 -0
  481. package/dist/lib/merge-tokens.generated.js +2 -2
  482. package/dist/showcase/foundations.d.ts.map +1 -1
  483. package/dist/showcase/foundations.js +10 -2
  484. package/dist/showcase/specimens/actions.d.ts +2 -0
  485. package/dist/showcase/specimens/actions.d.ts.map +1 -1
  486. package/dist/showcase/specimens/actions.js +30 -5
  487. package/dist/showcase/specimens/charts.d.ts.map +1 -1
  488. package/dist/showcase/specimens/charts.js +22 -13
  489. package/dist/showcase/specimens/choices.d.ts +14 -3
  490. package/dist/showcase/specimens/choices.d.ts.map +1 -1
  491. package/dist/showcase/specimens/choices.js +93 -13
  492. package/dist/showcase/specimens/compositions.d.ts.map +1 -1
  493. package/dist/showcase/specimens/compositions.js +136 -23
  494. package/dist/showcase/specimens/data.d.ts +12 -7
  495. package/dist/showcase/specimens/data.d.ts.map +1 -1
  496. package/dist/showcase/specimens/data.js +139 -35
  497. package/dist/showcase/specimens/feedback.d.ts +2 -0
  498. package/dist/showcase/specimens/feedback.d.ts.map +1 -1
  499. package/dist/showcase/specimens/feedback.js +39 -15
  500. package/dist/showcase/specimens/index.d.ts +20 -12
  501. package/dist/showcase/specimens/index.d.ts.map +1 -1
  502. package/dist/showcase/specimens/inputs.d.ts +4 -2
  503. package/dist/showcase/specimens/inputs.d.ts.map +1 -1
  504. package/dist/showcase/specimens/inputs.js +62 -19
  505. package/dist/showcase/specimens/menus.d.ts +0 -1
  506. package/dist/showcase/specimens/menus.d.ts.map +1 -1
  507. package/dist/showcase/specimens/menus.js +47 -17
  508. package/dist/showcase/specimens/navigation.d.ts +6 -4
  509. package/dist/showcase/specimens/navigation.d.ts.map +1 -1
  510. package/dist/showcase/specimens/navigation.js +61 -32
  511. package/dist/showcase/specimens/other.d.ts +1 -3
  512. package/dist/showcase/specimens/other.d.ts.map +1 -1
  513. package/dist/showcase/specimens/other.js +17 -13
  514. package/dist/showcase/specimens/status.d.ts +4 -1
  515. package/dist/showcase/specimens/status.d.ts.map +1 -1
  516. package/dist/showcase/specimens/status.js +64 -11
  517. package/dist/showcase/usage.generated.d.ts +1 -1
  518. package/dist/showcase/usage.generated.d.ts.map +1 -1
  519. package/dist/showcase/usage.generated.js +632 -544
  520. package/dist/standalone/index.js +1 -1
  521. package/dist/styles/components.css +13 -13
  522. package/dist/styles/globals.css +25 -0
  523. package/package.json +2 -3
  524. package/dist/components/approval-row.d.ts +0 -34
  525. package/dist/components/approval-row.d.ts.map +0 -1
  526. package/dist/components/approval-row.js +0 -27
  527. package/dist/components/channel-view.d.ts +0 -112
  528. package/dist/components/channel-view.d.ts.map +0 -1
  529. package/dist/components/channel-view.js +0 -84
  530. package/dist/components/dashboard-shell.d.ts +0 -51
  531. package/dist/components/dashboard-shell.d.ts.map +0 -1
  532. package/dist/components/dashboard-shell.js +0 -89
  533. package/dist/components/direction.d.ts +0 -2
  534. package/dist/components/direction.d.ts.map +0 -1
  535. package/dist/components/direction.js +0 -1
  536. package/dist/components/expandable-block.d.ts +0 -20
  537. package/dist/components/expandable-block.d.ts.map +0 -1
  538. package/dist/components/expandable-block.js +0 -32
  539. package/dist/components/form.d.ts +0 -42
  540. package/dist/components/form.d.ts.map +0 -1
  541. package/dist/components/form.js +0 -91
  542. package/dist/components/label-system.d.ts +0 -17
  543. package/dist/components/label-system.d.ts.map +0 -1
  544. package/dist/components/label-system.js +0 -21
  545. package/dist/components/memory-item.d.ts +0 -21
  546. package/dist/components/memory-item.d.ts.map +0 -1
  547. package/dist/components/memory-item.js +0 -18
  548. package/dist/components/menubar.d.ts +0 -43
  549. package/dist/components/menubar.d.ts.map +0 -1
  550. package/dist/components/menubar.js +0 -69
  551. package/dist/components/navigation-menu.d.ts +0 -26
  552. package/dist/components/navigation-menu.d.ts.map +0 -1
  553. package/dist/components/navigation-menu.js +0 -45
  554. package/dist/components/pagination.d.ts +0 -33
  555. package/dist/components/pagination.d.ts.map +0 -1
  556. package/dist/components/pagination.js +0 -41
  557. package/dist/components/plugin-slot-boundary.d.ts +0 -42
  558. package/dist/components/plugin-slot-boundary.d.ts.map +0 -1
  559. package/dist/components/plugin-slot-boundary.js +0 -41
  560. package/dist/components/status-row.d.ts +0 -32
  561. package/dist/components/status-row.d.ts.map +0 -1
  562. package/dist/components/status-row.js +0 -35
@@ -15,13 +15,19 @@ const ToggleGroupContext = React.createContext({
15
15
  * Pressed buttons that belong together.
16
16
  *
17
17
  * @family Choices
18
- * @when Pressed buttons that belong together: a list or grid view, which details a chat shows.
19
- * @instead A segmented control that sets a value, such as the theme or a period, is a `RadioGroup`
20
- * drawn with the toggle classes, as `ThemeModeSwitcher` does. Panels of one object are `Tabs`.
18
+ * @when Pressed buttons that belong together: which details a chat shows, the marks on a toolbar.
19
+ * @instead A value that is always exactly one of two or three, such as a list or grid view, is a
20
+ * `SegmentedControl`: its options are radios, so pressing the chosen one never clears it. The
21
+ * theme is `ThemeModeSwitcher`. Panels of one object are `Tabs`.
21
22
  * @behaviour Spacing 0 joins the members into one outline with one seam; spacing 2 keeps them 8 px
22
- * apart. Single or multiple pressed. Arrow keys move between members; Space presses.
23
- * @words Text members are short words of equal weight. Icon members always carry a name: *List*,
24
- * *Grid*.
23
+ * apart. With `multiple`, members are pressed independently and any number may be pressed, none
24
+ * included. Without it, at most one is pressed and pressing it again clears it; a value that is
25
+ * always one of two or three is a `SegmentedControl`. The group is named with `aria-label`
26
+ * or `aria-labelledby`, and a member is either a word as its children or carries an `aria-label`;
27
+ * a group or an icon member without a name does not compile. Colour: a pressed member takes the
28
+ * accent grey and nothing takes a hue. Arrow keys move between members; Space presses.
29
+ * @words Text members are short words of equal weight. Icon members always carry a name: *Tools*,
30
+ * *Reasoning*.
25
31
  * @access `role="group"` with a name; each member a button with `aria-pressed`.
26
32
  */
27
33
  function ToggleGroup({ className, variant, size, spacing = 2, orientation = "horizontal", style, children, ...props }) {
@@ -11,9 +11,12 @@ declare const toggleVariants: (props?: ({
11
11
  * @when A button that stays pressed, where pressing is the action: pin a chat, mute a thread, show
12
12
  * hidden rows in a toolbar.
13
13
  * @instead A setting saved with its section is a `Switch`. Choosing one value of several is a
14
- * `RadioGroup`, drawn segmented when it is short.
15
- * @behaviour Space or Enter flips `aria-pressed`. Pressed takes the accent fill and weight 600; the
16
- * label does not change. Hover is the muted fill. Disabled is 50%.
14
+ * `RadioGroup`, or a `SegmentedControl` when it is two or three views of one surface.
15
+ * @behaviour Space or Enter flips `aria-pressed`. Sizes, type, corners and the text inset are
16
+ * `Button`'s (32, 36 and 40 px; 12, 16 and 20 px), and the padding does not change with an icon; an icon-only toggle is square.
17
+ * Pressed takes the accent fill and weight 600, a neutral fill with no hue; the label does not
18
+ * change. Hover is the muted fill. Disable it only when pressing is impossible, and say why beside
19
+ * it.
17
20
  * @words The label is the action and stays the same in both states: *Pin*, never *Pinned* or
18
21
  * *Unpin*.
19
22
  * @access A `button` with `aria-pressed`. An icon-only toggle names what it does: *Pin chat*.
@@ -1 +1 @@
1
- {"version":3,"file":"toggle.d.ts","sourceRoot":"","sources":["../../src/components/toggle.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,cAAc;;;8EAoBnB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,+BAQ7D;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"toggle.d.ts","sourceRoot":"","sources":["../../src/components/toggle.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,IAAI,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIlE,QAAA,MAAM,cAAc;;;8EAmBnB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,iBAAS,MAAM,CAAC,EACd,SAAS,EACT,OAAmB,EACnB,IAAgB,EAChB,GAAG,KAAK,EACT,EAAE,eAAe,CAAC,KAAK,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,+BAQ7D;AAED,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC"}
@@ -3,16 +3,16 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
4
4
  import { cva } from "class-variance-authority";
5
5
  import { cn } from "../lib/utils.js";
6
- const toggleVariants = cva("group/toggle inline-flex min-h-touch-target min-w-touch-target items-center justify-center gap-1 rounded-sm border border-transparent text-sm font-medium whitespace-nowrap transition-[background-color,border-color,color,opacity] duration-[var(--nc-duration-confirm)] ease-[var(--nc-ease-out-strong)] hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-pressed:bg-accent aria-pressed:font-semibold aria-pressed:text-accent-foreground data-pressed:bg-accent data-pressed:font-semibold data-pressed:text-accent-foreground [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
6
+ const toggleVariants = cva("group/toggle inline-flex has-[>svg:only-child]:aspect-square has-[>svg:only-child]:px-0 min-h-touch-target min-w-touch-target items-center justify-center gap-1 rounded-sm border border-transparent text-button font-medium whitespace-nowrap transition-[background-color,border-color,color,opacity] duration-[var(--nc-duration-confirm)] ease-[var(--nc-ease-out-strong)] hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-pressed:bg-accent aria-pressed:font-semibold aria-pressed:text-accent-foreground data-pressed:bg-accent data-pressed:font-semibold data-pressed:text-accent-foreground [@media(hover:hover)_and_(pointer:fine)]:min-h-0 [@media(hover:hover)_and_(pointer:fine)]:min-w-0 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
7
7
  variants: {
8
8
  variant: {
9
9
  default: "bg-transparent",
10
10
  outline: "border-input bg-transparent hover:bg-muted",
11
11
  },
12
12
  size: {
13
- default: "h-control-height px-control-padding-inline has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
14
- sm: "h-nadicode-control-height-sm px-control-padding-inline text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
15
- lg: "h-nadicode-control-height-lg px-control-padding-inline has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
13
+ default: "h-control-height px-4",
14
+ sm: "h-nadicode-control-height-sm px-3 [&_svg:not([class*='size-'])]:size-3.5",
15
+ lg: "h-nadicode-control-height-lg rounded-md px-5 text-button-lg",
16
16
  },
17
17
  },
18
18
  defaultVariants: {
@@ -27,9 +27,12 @@ const toggleVariants = cva("group/toggle inline-flex min-h-touch-target min-w-to
27
27
  * @when A button that stays pressed, where pressing is the action: pin a chat, mute a thread, show
28
28
  * hidden rows in a toolbar.
29
29
  * @instead A setting saved with its section is a `Switch`. Choosing one value of several is a
30
- * `RadioGroup`, drawn segmented when it is short.
31
- * @behaviour Space or Enter flips `aria-pressed`. Pressed takes the accent fill and weight 600; the
32
- * label does not change. Hover is the muted fill. Disabled is 50%.
30
+ * `RadioGroup`, or a `SegmentedControl` when it is two or three views of one surface.
31
+ * @behaviour Space or Enter flips `aria-pressed`. Sizes, type, corners and the text inset are
32
+ * `Button`'s (32, 36 and 40 px; 12, 16 and 20 px), and the padding does not change with an icon; an icon-only toggle is square.
33
+ * Pressed takes the accent fill and weight 600, a neutral fill with no hue; the label does not
34
+ * change. Hover is the muted fill. Disable it only when pressing is impossible, and say why beside
35
+ * it.
33
36
  * @words The label is the action and stays the same in both states: *Pin*, never *Pinned* or
34
37
  * *Unpin*.
35
38
  * @access A `button` with `aria-pressed`. An icon-only toggle names what it does: *Pin chat*.
@@ -1,22 +1,53 @@
1
1
  import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
2
+ import type { PresentContent } from "../internal/present-content.js";
2
3
  declare function TooltipProvider({ delay, ...props }: TooltipPrimitive.Provider.Props): import("react").JSX.Element;
3
4
  /**
4
5
  * A short, optional fact about its trigger.
5
6
  *
6
7
  * @family Feedback
7
- * @when A short, optional fact the visible label cannot hold: why a value looks as it does, or an
8
- * icon-only button's name, a shortcut only when one is bound.
9
- * @instead For a preview with several facts use `HoverCard`. Help with a link uses a popover. A
10
- * disabled command's reason is written under it, never only here.
11
- * @behaviour Opens on hover and focus with no delay, above by default, 4 px off. Escape closes it.
12
- * Never interactive; never the only home of a warning, a price or a reason.
13
- * @words One phrase, sentence case, no full stop: *Resets on 1 November*. Never repeats the visible
14
- * label (*Save* on Save).
15
- * @access The trigger keeps its own name; the tooltip describes it. An icon-only button carries
16
- * `aria-label` whether or not the tooltip is open.
8
+ * @when "Use a Tooltip to explain **why** something exists, not **what** it is." "The visible label
9
+ * names the thing; the tooltip adds the constraint, scope, or limit."
10
+ * (https://vercel.com/geist/tooltip)
11
+ * "Use lifecycle Tooltips (`Alpha`, `Experimental`, `Beta`, `Early Access`) to name the limits that
12
+ * apply: API stability, SLA, support, pricing, retention." (https://vercel.com/geist/tooltip)
13
+ * Ours: a shortcut is shown in a tooltip only when one is bound.
14
+ * @instead "For an entity preview with metadata rows (avatar, identifier, 2–4 facts, optional
15
+ * action), use `Context Card`." "For long-form content or actions that need persistence, route to a
16
+ * `Drawer` or page navigation." (https://vercel.com/geist/tooltip)
17
+ * Ours: `Context Card` is `HoverCard` and `Drawer` is `Sheet`. A disabled command's reason is
18
+ * written under it, never only in a tooltip.
19
+ * @behaviour "Tooltips open on hover and on keyboard focus." "Keep the default ~150ms entry delay so
20
+ * the tooltip doesn’t flicker on a sweeping mouse." "Don’t wrap a labelled `Input` in a Tooltip."
21
+ * "The trigger lands on the `<label>`, not the field, and the tooltip text becomes a second
22
+ * invisible label for screen readers." "Put help on a sibling icon button." "Keep primary actions
23
+ * outside the Tooltip; touch users can’t reach a hover-revealed control."
24
+ * (https://vercel.com/geist/tooltip)
25
+ * Ours: the pointer wait is 150 ms and keyboard focus opens it at once; `delay={0}` on the trigger
26
+ * or a `TooltipProvider` removes the wait. Above by default, 10 px from the trigger, at most 250 px
27
+ * wide, 13 px text balanced over its lines. Never interactive. `arrow={false}` drops the stem;
28
+ * `centerText={false}` left-aligns a tooltip that wraps. `TooltipContent` requires its text as
29
+ * children. Colour: one inverted neutral, the page's ink as the fill and its surface as the
30
+ * text, with a stem of the same fill and no hue, in both themes; a shortcut is a `Kbd` after the
31
+ * text, drawn 20 px high.
32
+ * @words "One sentence or fragment in `text`." "Sentence case, no period for a single fragment."
33
+ * "Skip tooltips that repeat the visible label (`text="Rate Limit"` on a `Rate Limit` button) or
34
+ * describe the interaction (`text="Click to override"`)." "Lifecycle Tooltips follow `{Label}:
35
+ * {one-line meaning}. {Specific limit}.`" "For a paid Beta feature, combine the lifecycle and
36
+ * pricing in one Tooltip rather than stacking two badges." (https://vercel.com/geist/tooltip)
37
+ * Ours: the text is `TooltipContent`'s children, for example *Resets on 1 November*.
38
+ * @access "An icon-only trigger needs an `aria-label` that names the action; the Tooltip body adds
39
+ * context, it doesn’t replace the label." "Escape closes the tooltip and returns focus to the
40
+ * trigger." (https://vercel.com/geist/tooltip)
17
41
  */
18
42
  declare function Tooltip({ ...props }: TooltipPrimitive.Root.Props): import("react").JSX.Element;
19
- declare function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props): import("react").JSX.Element;
20
- declare function TooltipContent({ className, side, sideOffset, align, alignOffset, children, ...props }: TooltipPrimitive.Popup.Props & Pick<TooltipPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">): import("react").JSX.Element;
43
+ declare function TooltipTrigger({ delay, ...props }: TooltipPrimitive.Trigger.Props): import("react").JSX.Element;
44
+ declare function TooltipContent({ className, side, sideOffset, align, alignOffset, arrow, centerText, children, ...props }: TooltipPrimitive.Popup.Props & Pick<TooltipPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset"> & {
45
+ /** The text of the tooltip; a tooltip without one does not compile. */
46
+ children: PresentContent;
47
+ /** The stem pointing at the trigger; `false` for a tooltip that sits against it. */
48
+ arrow?: boolean;
49
+ /** Centres the text of a tooltip that wraps; `false` left-aligns it. */
50
+ centerText?: boolean;
51
+ }): import("react").JSX.Element;
21
52
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
22
53
  //# sourceMappingURL=tooltip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/components/tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAKrE,iBAAS,eAAe,CAAC,EAAE,KAAS,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAAK,+BAEhF;AAED;;;;;;;;;;;;;;GAcG;AACH,iBAAS,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,+BAEzD;AAED,iBAAS,cAAc,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,+BAEnE;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,IAAY,EACZ,UAAc,EACd,KAAgB,EAChB,WAAe,EACf,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,GAC7B,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,CAAC,+BAyBzF;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/components/tooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAIrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAQjE,iBAAS,eAAe,CAAC,EAAE,KAAqB,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,QAAQ,CAAC,KAAK,+BAM5F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,iBAAS,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,+BAEzD;AAED,iBAAS,cAAc,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,CAAC,OAAO,CAAC,KAAK,+BAS1E;AAED,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,IAAY,EACZ,UAAe,EACf,KAAgB,EAChB,WAAe,EACf,KAAY,EACZ,UAAiB,EACjB,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,gBAAgB,CAAC,KAAK,CAAC,KAAK,GAC7B,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,CAAC,GAAG;IACzF,uEAAuE;IACvE,QAAQ,EAAE,cAAc,CAAC;IACzB,oFAAoF;IACpF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,+BA8BF;AAED,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
@@ -1,32 +1,61 @@
1
+ "use client";
1
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
3
  import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
4
+ import { createContext, useContext } from "react";
5
+ import { overlayStem, OverlayStemShape } from "../internal/overlay-stem.js";
3
6
  import { cn } from "../lib/utils.js";
4
7
  import { anchoredOverlayMotion } from "../lib/motion.js";
5
- function TooltipProvider({ delay = 0, ...props }) {
6
- return _jsx(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delay: delay, ...props });
8
+ const TOOLTIP_DELAY = 150;
9
+ const TooltipDelay = createContext(TOOLTIP_DELAY);
10
+ function TooltipProvider({ delay = TOOLTIP_DELAY, ...props }) {
11
+ return (_jsx(TooltipDelay.Provider, { value: delay, children: _jsx(TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delay: delay, ...props }) }));
7
12
  }
8
13
  /**
9
14
  * A short, optional fact about its trigger.
10
15
  *
11
16
  * @family Feedback
12
- * @when A short, optional fact the visible label cannot hold: why a value looks as it does, or an
13
- * icon-only button's name, a shortcut only when one is bound.
14
- * @instead For a preview with several facts use `HoverCard`. Help with a link uses a popover. A
15
- * disabled command's reason is written under it, never only here.
16
- * @behaviour Opens on hover and focus with no delay, above by default, 4 px off. Escape closes it.
17
- * Never interactive; never the only home of a warning, a price or a reason.
18
- * @words One phrase, sentence case, no full stop: *Resets on 1 November*. Never repeats the visible
19
- * label (*Save* on Save).
20
- * @access The trigger keeps its own name; the tooltip describes it. An icon-only button carries
21
- * `aria-label` whether or not the tooltip is open.
17
+ * @when "Use a Tooltip to explain **why** something exists, not **what** it is." "The visible label
18
+ * names the thing; the tooltip adds the constraint, scope, or limit."
19
+ * (https://vercel.com/geist/tooltip)
20
+ * "Use lifecycle Tooltips (`Alpha`, `Experimental`, `Beta`, `Early Access`) to name the limits that
21
+ * apply: API stability, SLA, support, pricing, retention." (https://vercel.com/geist/tooltip)
22
+ * Ours: a shortcut is shown in a tooltip only when one is bound.
23
+ * @instead "For an entity preview with metadata rows (avatar, identifier, 2–4 facts, optional
24
+ * action), use `Context Card`." "For long-form content or actions that need persistence, route to a
25
+ * `Drawer` or page navigation." (https://vercel.com/geist/tooltip)
26
+ * Ours: `Context Card` is `HoverCard` and `Drawer` is `Sheet`. A disabled command's reason is
27
+ * written under it, never only in a tooltip.
28
+ * @behaviour "Tooltips open on hover and on keyboard focus." "Keep the default ~150ms entry delay so
29
+ * the tooltip doesn’t flicker on a sweeping mouse." "Don’t wrap a labelled `Input` in a Tooltip."
30
+ * "The trigger lands on the `<label>`, not the field, and the tooltip text becomes a second
31
+ * invisible label for screen readers." "Put help on a sibling icon button." "Keep primary actions
32
+ * outside the Tooltip; touch users can’t reach a hover-revealed control."
33
+ * (https://vercel.com/geist/tooltip)
34
+ * Ours: the pointer wait is 150 ms and keyboard focus opens it at once; `delay={0}` on the trigger
35
+ * or a `TooltipProvider` removes the wait. Above by default, 10 px from the trigger, at most 250 px
36
+ * wide, 13 px text balanced over its lines. Never interactive. `arrow={false}` drops the stem;
37
+ * `centerText={false}` left-aligns a tooltip that wraps. `TooltipContent` requires its text as
38
+ * children. Colour: one inverted neutral, the page's ink as the fill and its surface as the
39
+ * text, with a stem of the same fill and no hue, in both themes; a shortcut is a `Kbd` after the
40
+ * text, drawn 20 px high.
41
+ * @words "One sentence or fragment in `text`." "Sentence case, no period for a single fragment."
42
+ * "Skip tooltips that repeat the visible label (`text="Rate Limit"` on a `Rate Limit` button) or
43
+ * describe the interaction (`text="Click to override"`)." "Lifecycle Tooltips follow `{Label}:
44
+ * {one-line meaning}. {Specific limit}.`" "For a paid Beta feature, combine the lifecycle and
45
+ * pricing in one Tooltip rather than stacking two badges." (https://vercel.com/geist/tooltip)
46
+ * Ours: the text is `TooltipContent`'s children, for example *Resets on 1 November*.
47
+ * @access "An icon-only trigger needs an `aria-label` that names the action; the Tooltip body adds
48
+ * context, it doesn’t replace the label." "Escape closes the tooltip and returns focus to the
49
+ * trigger." (https://vercel.com/geist/tooltip)
22
50
  */
23
51
  function Tooltip({ ...props }) {
24
52
  return _jsx(TooltipPrimitive.Root, { "data-slot": "tooltip", ...props });
25
53
  }
26
- function TooltipTrigger({ ...props }) {
27
- return _jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", ...props });
54
+ function TooltipTrigger({ delay, ...props }) {
55
+ const inheritedDelay = useContext(TooltipDelay);
56
+ return (_jsx(TooltipPrimitive.Trigger, { "data-slot": "tooltip-trigger", delay: delay ?? inheritedDelay, ...props }));
28
57
  }
29
- function TooltipContent({ className, side = "top", sideOffset = 4, align = "center", alignOffset = 0, children, ...props }) {
30
- return (_jsx(TooltipPrimitive.Portal, { children: _jsx(TooltipPrimitive.Positioner, { align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, className: "isolate z-50", children: _jsxs(TooltipPrimitive.Popup, { "data-slot": "tooltip-content", className: cn("z-50 inline-flex w-fit max-w-xs items-center gap-1.5 rounded-sm border-0 bg-popover px-nadicode-sm py-1.5 text-body-sm text-popover-foreground nc-elevation-floating has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm", anchoredOverlayMotion, className), ...props, children: [children, _jsx(TooltipPrimitive.Arrow, { className: "z-50 size-2.5 translate-y-[calc(-50%-var(--nc-rounded-xs))] rotate-45 rounded-xs border border-border bg-popover fill-popover data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" })] }) }) }));
58
+ function TooltipContent({ className, side = "top", sideOffset = 10, align = "center", alignOffset = 0, arrow = true, centerText = true, children, ...props }) {
59
+ return (_jsx(TooltipPrimitive.Portal, { children: _jsx(TooltipPrimitive.Positioner, { align: align, alignOffset: alignOffset, side: side, sideOffset: sideOffset, className: "isolate z-50", children: _jsxs(TooltipPrimitive.Popup, { "data-slot": "tooltip-content", className: cn("z-50 w-fit max-w-62.5 rounded-md border-0 bg-foreground px-nadicode-xs py-1.5 text-body-compact text-balance text-background nc-elevation-floating has-data-[slot=kbd]:inline-flex has-data-[slot=kbd]:items-center has-data-[slot=kbd]:gap-1 has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:h-5 **:data-[slot=kbd]:min-w-5 **:data-[slot=kbd]:text-caption **:data-[slot=kbd]:leading-5", centerText ? "text-center" : "text-left", anchoredOverlayMotion, className), ...props, children: [children, arrow ? (_jsx(TooltipPrimitive.Arrow, { className: cn(overlayStem, "[&_path]:fill-foreground"), children: _jsx(OverlayStemShape, {}) })) : null] }) }) }));
31
60
  }
32
61
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
@@ -34,6 +34,6 @@ function trendTone(direction, upIsGood = true, neutral = false) {
34
34
  */
35
35
  function TrendBadge({ value, direction, tone, directionLabel, }) {
36
36
  const Icon = TREND_ICONS[direction];
37
- return (_jsxs(Badge, { "data-slot": "trend-badge", "data-direction": direction, "data-tone": tone, variant: "outline", className: "tabular-nums", children: [_jsx(Icon, { "aria-hidden": "true", className: TREND_TONE_CLASS[tone] }), _jsx("span", { className: "sr-only", children: directionLabel }), value] }));
37
+ return (_jsxs(Badge, { "data-slot": "trend-badge", "data-direction": direction, "data-tone": tone, variant: "outline", className: "tabular-nums", icon: _jsx(Icon, { "aria-hidden": "true", className: TREND_TONE_CLASS[tone] }), children: [_jsx("span", { className: "sr-only", children: directionLabel }), value] }));
38
38
  }
39
39
  export { TrendBadge, trendTone };
@@ -21,7 +21,7 @@ export function UpdateCard(props) {
21
21
  return (_jsxs(Card, { "aria-label": props.title, className: "mx-1 mb-1", "data-state": props.state, render: _jsx("section", {}), size: "sm", surface: "outlined", children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: props.title }), _jsx(CardDescription, { children: props.version }), props.state === "updated" ? (_jsx(CardAction, { children: _jsx(Button, { "aria-label": props.dismiss.label, onClick: props.dismiss.onClick, size: "icon-sm", type: "button", variant: "ghost", children: _jsx(X, { "aria-hidden": "true" }) }) })) : null] }), props.state === "available" ? (_jsx(CardContent, { className: "grid *:w-full", children: _jsx(PageCommandButton, { command: props.action, variant: "default" }) })) : null] }));
22
22
  }
23
23
  function NarrowUpdate(props) {
24
- const button = props.state === "available" ? (_jsx(Button, { "aria-busy": props.action.pending || undefined, "aria-label": `${props.action.pending ? (props.action.pendingLabel ?? props.action.label) : props.action.label}: ${props.version}`, disabled: props.action.disabled || props.action.pending, size: "icon", variant: "ghost", ...(props.action.render
24
+ const button = props.state === "available" ? (_jsx(Button, { "aria-label": `${props.action.pending ? (props.action.pendingLabel ?? props.action.label) : props.action.label}: ${props.version}`, disabled: props.action.disabled, loading: props.action.pending, size: "icon", variant: "ghost", ...(props.action.render
25
25
  ? { render: props.action.render, nativeButton: false }
26
26
  : { onClick: props.action.onClick, type: "button" }), children: _jsx(ArrowDownToLine, { "aria-hidden": "true" }) })) : (_jsx(Button, { "aria-label": `${props.dismiss.label}: ${props.title}`, onClick: props.dismiss.onClick, size: "icon", type: "button", variant: "ghost", children: _jsx(CircleCheck, { "aria-hidden": "true" }) }));
27
27
  return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { render: button }), _jsxs(TooltipContent, { side: "right", children: [props.title, ", ", props.version] })] }));
@@ -3,20 +3,61 @@ import { readdirSync, readFileSync } from "node:fs";
3
3
 
4
4
  import { builtinRules } from "eslint/use-at-your-own-risk";
5
5
 
6
+ import { badgeIsStaticLabel } from "./rules/badge-is-static-label.js";
7
+ import { buttonIconSlot } from "./rules/button-icon-slot.js";
8
+ import { buttonLinkForNavigation } from "./rules/button-link-for-navigation.js";
9
+ import { buttonNoAriaLabelWithText } from "./rules/button-no-aria-label-with-text.js";
10
+ import { buttonTypeRolesOnlyInButtons } from "./rules/button-type-roles-only-in-buttons.js";
11
+ import { choiceControlHasAName } from "./rules/choice-control-has-a-name.js";
12
+ import { choiceGroupInFieldset } from "./rules/choice-group-in-fieldset.js";
13
+ import { commandShortcutSingleOwner } from "./rules/command-shortcut-single-owner.js";
14
+ import { confirmDialogWords } from "./rules/confirm-dialog-words.js";
15
+ import { dataTableOneUnsizedColumn } from "./rules/data-table-one-unsized-column.js";
16
+ import { destructiveActionPlacement } from "./rules/destructive-action-placement.js";
17
+ import { disabledChoiceSaysWhy } from "./rules/disabled-choice-says-why.js";
18
+ import { settingsLimitInFooter } from "./rules/settings-limit-in-footer.js";
19
+ import { ellipsisOpensADialog } from "./rules/ellipsis-opens-a-dialog.js";
6
20
  import { emptyStateOwner } from "./rules/empty-state-owner.js";
21
+ import { inputGroupOwners } from "./rules/input-group-owners.js";
22
+ import { kbdChildrenNoModifierText } from "./rules/kbd-children-no-modifier-text.js";
7
23
  import { menuOwner } from "./rules/menu-owner.js";
24
+ import { middleTruncatePlacement } from "./rules/middle-truncate-placement.js";
8
25
  import { noAppFeatureComponent } from "./rules/no-app-feature-component.js";
26
+ import { noBareButtonLabel } from "./rules/no-bare-button-label.js";
9
27
  import { noChoiceControlWrapper } from "./rules/no-choice-control-wrapper.js";
10
28
  import { noComment } from "./rules/no-comment.js";
29
+ import { noControlInReadOnlySurface } from "./rules/no-control-in-read-only-surface.js";
11
30
  import { noDecorativeIcon } from "./rules/no-decorative-icon.js";
12
31
  import { noDeprecatedZodApi } from "./rules/no-deprecated-zod-api.js";
13
32
  import { noGlobalPatch } from "./rules/no-global-patch.js";
33
+ import { noHandBuiltBusy } from "./rules/no-hand-built-busy.js";
34
+ import { noHandBuiltThemePicker } from "./rules/no-hand-built-theme-picker.js";
35
+ import { noHandBuiltTile } from "./rules/no-hand-built-tile.js";
36
+ import { noHandFormattedDate } from "./rules/no-hand-formatted-date.js";
37
+ import { noHandStackedAvatars } from "./rules/no-hand-stacked-avatars.js";
38
+ import { noNestedCollapse } from "./rules/no-nested-collapse.js";
14
39
  import { noPackageComponentRedefinition } from "./rules/no-package-component-redefinition.js";
40
+ import { noSearchInForm } from "./rules/no-search-in-form.js";
15
41
  import { noShadcnAppearanceOverride } from "./rules/no-shadcn-appearance-override.js";
42
+ import { noShellPromptInSnippet } from "./rules/no-shell-prompt-in-snippet.js";
43
+ import { noStockErrorWords } from "./rules/no-stock-error-words.js";
16
44
  import { noSubjectDerivedExpectation } from "./rules/no-subject-derived-expectation.js";
45
+ import { noTooltipAroundLabelledField } from "./rules/no-tooltip-around-labelled-field.js";
46
+ import { noWeightClassOnStrongInTypeRole } from "./rules/no-weight-class-on-strong-in-type-role.js";
17
47
  import { noWriteInSubscription } from "./rules/no-write-in-subscription.js";
48
+ import { oneSubmenuLevel } from "./rules/one-submenu-level.js";
49
+ import { oneToastPerFlow } from "./rules/one-toast-per-flow.js";
50
+ import { optionCount } from "./rules/option-count.js";
51
+ import { pageCommandLinkNotRender } from "./rules/page-command-link-not-render.js";
18
52
  import { pageComposition } from "./rules/page-composition.js";
53
+ import { progressNeedsName } from "./rules/progress-needs-name.js";
19
54
  import { serverActionDiscipline } from "./rules/server-action-discipline.js";
55
+ import { skeletonInRegion } from "./rules/skeleton-in-region.js";
56
+ import { sortableHeadingUsesSort } from "./rules/sortable-heading-uses-sort.js";
57
+ import { tableCellInsetOwner } from "./rules/table-cell-inset-owner.js";
58
+ import { tabsSelectionIsControlled } from "./rules/tabs-selection-is-controlled.js";
59
+ import { tooltipOnlyArrow } from "./rules/tooltip-only-arrow.js";
60
+ import { tooltipTriggerAccessibleName } from "./rules/tooltip-trigger-accessible-name.js";
20
61
  import { strictDesignSystemSelectors } from "./strict-design-system.js";
21
62
 
22
63
  /**
@@ -106,20 +147,61 @@ const plugin = {
106
147
  configs: {},
107
148
  rules: {
108
149
  ...strictSelectorRules,
150
+ "badge-is-static-label": badgeIsStaticLabel,
151
+ "button-icon-slot": buttonIconSlot,
152
+ "button-link-for-navigation": buttonLinkForNavigation,
153
+ "button-no-aria-label-with-text": buttonNoAriaLabelWithText,
154
+ "button-type-roles-only-in-buttons": buttonTypeRolesOnlyInButtons,
155
+ "choice-control-has-a-name": choiceControlHasAName,
156
+ "choice-group-in-fieldset": choiceGroupInFieldset,
157
+ "command-shortcut-single-owner": commandShortcutSingleOwner,
158
+ "confirm-dialog-words": confirmDialogWords,
159
+ "data-table-one-unsized-column": dataTableOneUnsizedColumn,
160
+ "destructive-action-placement": destructiveActionPlacement,
161
+ "disabled-choice-says-why": disabledChoiceSaysWhy,
162
+ "settings-limit-in-footer": settingsLimitInFooter,
163
+ "ellipsis-opens-a-dialog": ellipsisOpensADialog,
109
164
  "empty-state-owner": emptyStateOwner,
165
+ "input-group-owners": inputGroupOwners,
166
+ "kbd-children-no-modifier-text": kbdChildrenNoModifierText,
110
167
  "menu-owner": menuOwner,
168
+ "middle-truncate-placement": middleTruncatePlacement,
111
169
  "no-app-feature-component": noAppFeatureComponent,
170
+ "no-bare-button-label": noBareButtonLabel,
112
171
  "no-choice-control-wrapper": noChoiceControlWrapper,
113
172
  "no-comment": noComment,
173
+ "no-control-in-read-only-surface": noControlInReadOnlySurface,
114
174
  "no-decorative-icon": noDecorativeIcon,
115
175
  "no-deprecated-zod-api": noDeprecatedZodApi,
116
176
  "no-global-patch": noGlobalPatch,
177
+ "no-hand-built-busy": noHandBuiltBusy,
178
+ "no-hand-built-theme-picker": noHandBuiltThemePicker,
179
+ "no-hand-built-tile": noHandBuiltTile,
180
+ "no-hand-formatted-date": noHandFormattedDate,
181
+ "no-hand-stacked-avatars": noHandStackedAvatars,
182
+ "no-nested-collapse": noNestedCollapse,
117
183
  "no-package-component-redefinition": noPackageComponentRedefinition,
184
+ "no-search-in-form": noSearchInForm,
118
185
  "no-shadcn-appearance-override": noShadcnAppearanceOverride,
186
+ "no-shell-prompt-in-snippet": noShellPromptInSnippet,
187
+ "no-stock-error-words": noStockErrorWords,
119
188
  "no-subject-derived-expectation": noSubjectDerivedExpectation,
189
+ "no-tooltip-around-labelled-field": noTooltipAroundLabelledField,
190
+ "no-weight-class-on-strong-in-type-role": noWeightClassOnStrongInTypeRole,
120
191
  "no-write-in-subscription": noWriteInSubscription,
192
+ "one-submenu-level": oneSubmenuLevel,
193
+ "one-toast-per-flow": oneToastPerFlow,
194
+ "option-count": optionCount,
195
+ "page-command-link-not-render": pageCommandLinkNotRender,
121
196
  "page-composition": pageComposition,
197
+ "progress-needs-name": progressNeedsName,
122
198
  "server-action-discipline": serverActionDiscipline,
199
+ "skeleton-in-region": skeletonInRegion,
200
+ "sortable-heading-uses-sort": sortableHeadingUsesSort,
201
+ "table-cell-inset-owner": tableCellInsetOwner,
202
+ "tabs-selection-is-controlled": tabsSelectionIsControlled,
203
+ "tooltip-only-arrow": tooltipOnlyArrow,
204
+ "tooltip-trigger-accessible-name": tooltipTriggerAccessibleName,
123
205
  },
124
206
  };
125
207
 
@@ -0,0 +1,93 @@
1
+ /*
2
+ * Standard tool checked first: a `no-restricted-syntax` selector such as
3
+ * `Badge Badge` matches a name written in the file, not the element bound to
4
+ * the package's Badge, so it misses a renamed import and flags a product's own
5
+ * `Badge`; and `Badge[icon]` cannot tell a label inside the `icon` prop from
6
+ * an icon. This rule joins each element to its import first.
7
+ */
8
+ import { partOf, renderedImports, staticAttribute } from "./rendered-import.js";
9
+
10
+ const exportedBy = (module) => [
11
+ { from: `@nadicodeai/ui/components/${module}`, part: module },
12
+ { from: "@nadicodeai/ui", part: module },
13
+ { from: `@/components/${module}`, part: module },
14
+ ];
15
+
16
+ const PARTS = new Map([
17
+ ["Badge", exportedBy("badge")],
18
+ [
19
+ "StatusBadge",
20
+ [
21
+ ...exportedBy("status-badge"),
22
+ { from: "@/components/kit/status-badge", part: "status-badge" },
23
+ ],
24
+ ],
25
+ ["Tag", exportedBy("tag")],
26
+ ["TrendBadge", exportedBy("trend-badge")],
27
+ ]);
28
+
29
+ const HOSTS = new Set(["badge", "status-badge"]);
30
+ const BUTTON_ATTRIBUTES = new Set(["tabIndex", "aria-pressed", "onKeyDown", "onKeyUp"]);
31
+
32
+ const attributeName = (attribute) =>
33
+ attribute.type === "JSXAttribute" && attribute.name.type === "JSXIdentifier"
34
+ ? attribute.name.name
35
+ : null;
36
+
37
+ export const badgeIsStaticLabel = {
38
+ meta: {
39
+ type: "problem",
40
+ docs: {
41
+ description:
42
+ "A Badge or StatusBadge is a static label: no label inside it, no button behaviour on it.",
43
+ },
44
+ schema: [],
45
+ messages: {
46
+ "static-label":
47
+ 'A badge is a static label of text, or one icon and text. Put a second label beside it; a value that can be acted on is a Button, or a link with <Badge render={<a href=... />} variant="pill">.',
48
+ },
49
+ },
50
+ create(context) {
51
+ const importOf = renderedImports(context);
52
+ const partOfElement = (element) =>
53
+ partOf(importOf(element.openingElement.name), PARTS, context.filename);
54
+ const isHost = (opening) => HOSTS.has(partOf(importOf(opening.name), PARTS, context.filename));
55
+
56
+ function holdingHost(label) {
57
+ let child = label;
58
+ for (let current = label.parent; current; child = current, current = current.parent) {
59
+ const holdsAsChild =
60
+ current.type === "JSXElement" &&
61
+ current.children.includes(child) &&
62
+ isHost(current.openingElement);
63
+ if (holdsAsChild) return current;
64
+ if (
65
+ current.type === "JSXAttribute" &&
66
+ attributeName(current) === "icon" &&
67
+ isHost(current.parent)
68
+ ) {
69
+ return current.parent;
70
+ }
71
+ }
72
+ return null;
73
+ }
74
+
75
+ return {
76
+ JSXElement(node) {
77
+ if (partOfElement(node) && holdingHost(node)) {
78
+ context.report({ node, messageId: "static-label" });
79
+ }
80
+ },
81
+ JSXOpeningElement(node) {
82
+ if (!isHost(node)) return;
83
+ for (const attribute of node.attributes) {
84
+ const name = attributeName(attribute);
85
+ const refused =
86
+ BUTTON_ATTRIBUTES.has(name) ||
87
+ (name === "role" && staticAttribute(node, "role") === "button");
88
+ if (refused) context.report({ node: attribute, messageId: "static-label" });
89
+ }
90
+ },
91
+ };
92
+ },
93
+ };
@@ -0,0 +1,102 @@
1
+ /*
2
+ * Standard tool checked first: the `repo/shadcn-composition` selector in the
3
+ * root config (`Button JSXOpeningElement[name.name=/Icon$/]` without
4
+ * `data-icon`) matches by element name under any `Button`, so it cannot tell a
5
+ * text Button from an icon-only one (the size decides where an icon goes), nor
6
+ * a `Button` imported from `@nadicodeai/ui` from a local one, nor an icon bound
7
+ * to an icon module from a component that only ends in `Icon`.
8
+ */
9
+ import {
10
+ PACKAGE_BARREL,
11
+ partOf,
12
+ renderedImports,
13
+ sourceMatches,
14
+ staticAttribute,
15
+ writtenName,
16
+ } from "./rendered-import.js";
17
+
18
+ const BUTTONS = new Map(
19
+ ["Button", "ButtonLink"].map((name) => [
20
+ name,
21
+ ["@nadicodeai/ui/components/button", PACKAGE_BARREL].map((from) => ({ from, part: name })),
22
+ ]),
23
+ );
24
+
25
+ const TEXT_SIZES = new Set(["default", "xs", "sm", "lg"]);
26
+
27
+ const isAttribute = (attribute, name) =>
28
+ attribute.type === "JSXAttribute" && attribute.name.name === name;
29
+
30
+ export const buttonIconSlot = {
31
+ meta: {
32
+ type: "problem",
33
+ docs: {
34
+ description:
35
+ "A text Button takes its icon as prefix or suffix; an icon-only Button takes the icon as its child with no data-icon.",
36
+ },
37
+ schema: [
38
+ {
39
+ type: "object",
40
+ properties: {
41
+ iconModules: { type: "array", items: { type: "string" }, uniqueItems: true },
42
+ },
43
+ additionalProperties: false,
44
+ },
45
+ ],
46
+ defaultOptions: [{ iconModules: ["lucide-react", "@nadicodeai/ui/components/house-icons"] }],
47
+ messages: {
48
+ "icon-slot":
49
+ 'Pass an icon in a text Button as prefix={<Icon />} or suffix={<Icon />}; an icon-only Button (size="icon") takes the icon as its child.',
50
+ },
51
+ },
52
+ create(context) {
53
+ const [{ iconModules }] = context.options;
54
+ const importOf = renderedImports(context);
55
+ const isButton = (openingElement) =>
56
+ partOf(importOf(openingElement.name), BUTTONS, context.filename) !== null;
57
+
58
+ const isIcon = (openingElement) => {
59
+ const imported = importOf(openingElement.name);
60
+ if (
61
+ imported &&
62
+ iconModules.some((module) => sourceMatches(imported.source, module, context.filename))
63
+ ) {
64
+ return true;
65
+ }
66
+ return /Icon$/.test(writtenName(openingElement.name) ?? "");
67
+ };
68
+
69
+ function enclosingButton(node) {
70
+ for (let current = node.parent.parent; current; current = current.parent) {
71
+ if (current.type === "JSXAttribute") return null;
72
+ if (current.type === "JSXElement" && isButton(current.openingElement)) {
73
+ return current.openingElement;
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+
79
+ function takesTextSize(button) {
80
+ if (button.attributes.some((attribute) => attribute.type === "JSXSpreadAttribute")) {
81
+ return false;
82
+ }
83
+ if (!button.attributes.some((attribute) => isAttribute(attribute, "size"))) return true;
84
+ return TEXT_SIZES.has(staticAttribute(button, "size"));
85
+ }
86
+
87
+ return {
88
+ JSXOpeningElement(node) {
89
+ if (node.parent.type !== "JSXElement") return;
90
+ const carriesDataIcon = node.attributes.some((attribute) =>
91
+ isAttribute(attribute, "data-icon"),
92
+ );
93
+ if (!carriesDataIcon && !isIcon(node)) return;
94
+ const button = enclosingButton(node);
95
+ if (!button) return;
96
+ if (carriesDataIcon || takesTextSize(button)) {
97
+ context.report({ node, messageId: "icon-slot" });
98
+ }
99
+ },
100
+ };
101
+ },
102
+ };