@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
@@ -0,0 +1,60 @@
1
+ /*
2
+ * Standard tool checked first: a `no-restricted-syntax` descendant selector
3
+ * matches by element name, so it cannot tell the package's Accordion from a
4
+ * local component of the same name, a renamed import, or a Disclosure's
5
+ * `label` (which is not its content) from its children.
6
+ */
7
+ import { packageModules, partOf, renderedImports } from "./rendered-import.js";
8
+
9
+ const PARTS = [
10
+ ["accordion", "Accordion"],
11
+ ["accordion", "AccordionContent"],
12
+ ["collapsible", "Collapsible"],
13
+ ["collapsible", "CollapsibleContent"],
14
+ ["disclosure", "Disclosure"],
15
+ ];
16
+
17
+ const PART_EXPORTERS = new Map(
18
+ PARTS.map(([module, part]) => [
19
+ part,
20
+ [...packageModules(module), `@/components/${module}`].map((from) => ({ from, part })),
21
+ ]),
22
+ );
23
+
24
+ const COLLAPSES = new Set(["Accordion", "Collapsible", "Disclosure"]);
25
+ const COLLAPSED_CONTENT = new Set(["AccordionContent", "CollapsibleContent", "Disclosure"]);
26
+
27
+ export const noNestedCollapse = {
28
+ meta: {
29
+ type: "problem",
30
+ docs: {
31
+ description: "An Accordion, Collapsible or Disclosure never sits in another's content.",
32
+ },
33
+ schema: [],
34
+ messages: {
35
+ "nested-collapse":
36
+ "A collapse never sits in another: two levels hide too much and break the keyboard path. Make the inner one a section of the page, or flatten the outer.",
37
+ },
38
+ },
39
+ create(context) {
40
+ const importOf = renderedImports(context);
41
+ const partRendered = (element) =>
42
+ partOf(importOf(element.openingElement.name), PART_EXPORTERS, context.filename);
43
+
44
+ return {
45
+ JSXElement(node) {
46
+ if (!COLLAPSES.has(partRendered(node))) return;
47
+ let child = node;
48
+ for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
49
+ const holdsAsContent =
50
+ ancestor.type === "JSXElement" && ancestor.children.includes(child);
51
+ if (holdsAsContent && COLLAPSED_CONTENT.has(partRendered(ancestor))) {
52
+ context.report({ node, messageId: "nested-collapse" });
53
+ return;
54
+ }
55
+ child = ancestor;
56
+ }
57
+ },
58
+ };
59
+ },
60
+ };
@@ -0,0 +1,47 @@
1
+ /*
2
+ * Standard tool checked first: a `no-restricted-syntax` descendant selector
3
+ * (`JSXElement[openingElement.name.name=/Form$/] JSXOpeningElement`) matches by
4
+ * element name, so it cannot tell the package's CollectionSearch from a local
5
+ * component of the same name, nor a renamed import.
6
+ */
7
+ import { packageModules, partOf, renderedImports, writtenName } from "./rendered-import.js";
8
+
9
+ const COLLECTION_SEARCH = new Map([
10
+ [
11
+ "CollectionSearch",
12
+ packageModules("collection-search").map((from) => ({ from, part: "CollectionSearch" })),
13
+ ],
14
+ ]);
15
+
16
+ const isForm = (element) => {
17
+ const name = writtenName(element.openingElement.name);
18
+ return name === "form" || name?.endsWith("Form") === true;
19
+ };
20
+
21
+ export const noSearchInForm = {
22
+ meta: {
23
+ type: "problem",
24
+ docs: {
25
+ description: "A collection's search sits in its toolbar, never inside a form that saves.",
26
+ },
27
+ schema: [],
28
+ messages: {
29
+ "search-in-form":
30
+ "A search box does not belong in a form that saves something; a collection's search sits in its toolbar.",
31
+ },
32
+ },
33
+ create(context) {
34
+ const importOf = renderedImports(context);
35
+ return {
36
+ JSXOpeningElement(node) {
37
+ if (partOf(importOf(node.name), COLLECTION_SEARCH, context.filename) === null) return;
38
+ for (let ancestor = node.parent.parent; ancestor; ancestor = ancestor.parent) {
39
+ if (ancestor.type === "JSXElement" && isForm(ancestor)) {
40
+ context.report({ node, messageId: "search-in-form" });
41
+ return;
42
+ }
43
+ }
44
+ },
45
+ };
46
+ },
47
+ };
@@ -21,9 +21,8 @@ import {
21
21
  skipsPackageOwnedPrimitive,
22
22
  } from "./jsx-class-utility.js";
23
23
 
24
- // These exact Portal adapters forward props to package primitives. Card
25
- // chooses its typed surface default; Table owns only structural geometry.
26
- // Their other exports are direct reexports.
24
+ // This exact Portal adapter forwards props to package primitives. Card
25
+ // chooses its typed surface default. Its other exports are direct reexports.
27
26
  const portalCardExports = new Set([
28
27
  "Card",
29
28
  "CardHeader",
@@ -32,16 +31,6 @@ const portalCardExports = new Set([
32
31
  "CardAction",
33
32
  "CardContent",
34
33
  ]);
35
- const portalTableExports = new Set([
36
- "Table",
37
- "TableHead",
38
- "TableCell",
39
- "TableBody",
40
- "TableCaption",
41
- "TableFooter",
42
- "TableHeader",
43
- "TableRow",
44
- ]);
45
34
 
46
35
  function primitiveModule(source, filename) {
47
36
  if (source.startsWith("@nadicodeai/ui/components/")) {
@@ -57,9 +46,6 @@ function primitiveModule(source, filename) {
57
46
  if (source === "@/components/kit/card" || resolved === `${portalSource}/components/kit/card`) {
58
47
  return { card: true, exports: portalCardExports };
59
48
  }
60
- if (source === "@/components/kit/table" || resolved === `${portalSource}/components/kit/table`) {
61
- return { card: false, exports: portalTableExports };
62
- }
63
49
  return undefined;
64
50
  }
65
51
 
@@ -0,0 +1,74 @@
1
+ /*
2
+ * A Snippet draws its own prompt and copies only the command, so a `$ ` or `> `
3
+ * typed into `text` shows twice and is on the clipboard.
4
+ *
5
+ * Standard tool checked first: `no-restricted-syntax` can match a string
6
+ * starting with `$ `, but not whether it is the `text` of the package's Snippet
7
+ * (an import binding, so a renamed or local `Snippet` is judged correctly),
8
+ * and it cannot read the items of an array or exempt `prompt={false}`.
9
+ */
10
+ import { partOf, renderedImports, staticAttribute } from "./rendered-import.js";
11
+
12
+ const SNIPPET = new Map([
13
+ [
14
+ "Snippet",
15
+ [
16
+ { from: "@nadicodeai/ui/components/snippet", part: "Snippet" },
17
+ { from: "@nadicodeai/ui", part: "Snippet" },
18
+ ],
19
+ ],
20
+ ]);
21
+ const OWNER_FILE = "packages/ui/src/components/snippet.tsx";
22
+
23
+ const startsWithPrompt = (text) => text === "$" || text.startsWith("$ ") || text.startsWith("> ");
24
+
25
+ function writtenText(node) {
26
+ // oxlint-disable-next-line anti-slop/no-runtime-typeof -- ESTree types Literal.value as string | number | boolean | RegExp | bigint | null; only typeof picks the string.
27
+ if (node.type === "Literal") return typeof node.value === "string" ? node.value : null;
28
+ if (node.type === "TemplateLiteral" && node.expressions.length === 0) {
29
+ return node.quasis[0].value.cooked;
30
+ }
31
+ return null;
32
+ }
33
+
34
+ function promptedItems(value) {
35
+ if (!value) return [];
36
+ const written = value.type === "JSXExpressionContainer" ? value.expression : value;
37
+ const items = written.type === "ArrayExpression" ? written.elements : [written];
38
+ return items.filter((item) => {
39
+ if (!item || item.type === "SpreadElement") return false;
40
+ const text = writtenText(item);
41
+ return text !== null && startsWithPrompt(text);
42
+ });
43
+ }
44
+
45
+ export const noShellPromptInSnippet = {
46
+ meta: {
47
+ type: "problem",
48
+ docs: {
49
+ description: "A Snippet's text never starts with the prompt the Snippet draws.",
50
+ },
51
+ schema: [],
52
+ messages: {
53
+ "typed-prompt":
54
+ 'The Snippet draws the prompt. Remove the leading "$ " from text, or pass prompt={false} when the value is not a shell command.',
55
+ },
56
+ },
57
+ create(context) {
58
+ if (context.filename.replaceAll("\\", "/").endsWith(`/${OWNER_FILE}`)) return {};
59
+ const importOf = renderedImports(context);
60
+
61
+ return {
62
+ JSXOpeningElement(node) {
63
+ if (partOf(importOf(node.name), SNIPPET, context.filename) !== "Snippet") return;
64
+ if (staticAttribute(node, "prompt") === false) return;
65
+ const text = node.attributes.find(
66
+ (attribute) => attribute.type === "JSXAttribute" && attribute.name.name === "text",
67
+ );
68
+ for (const item of promptedItems(text?.value)) {
69
+ context.report({ node: item, messageId: "typed-prompt" });
70
+ }
71
+ },
72
+ };
73
+ },
74
+ };
@@ -0,0 +1,56 @@
1
+ /*
2
+ * Standard tool checked first: `no-restricted-syntax` matches a string by one
3
+ * regular expression per selector and would need one entry per phrase and per
4
+ * node kind (a literal, a template's text, JSX text); one rule lists the
5
+ * phrases once and reads them in the catalogue files only, by path.
6
+ */
7
+ import { literalText } from "./literal-text.js";
8
+
9
+ const PHRASES = [
10
+ ["Something went wrong", /\bsomething went wrong\b/i],
11
+ ["Unable to", /\bunable to\b/i],
12
+ ["Heads up", /\bheads[ -]up\b/i],
13
+ ["please", /\bplease\b/i],
14
+ ["successfully", /\bsuccessfully\b/i],
15
+ ];
16
+
17
+ const CATALOGUE_FILE = /(?:^|\/)(?:copy|i18n)\/|(?:^|\/)(?:words|messages)\.[jt]s$/;
18
+ const TEST_FILE = /\.test\.[jt]sx?$/;
19
+
20
+ export const noStockErrorWords = {
21
+ meta: {
22
+ type: "problem",
23
+ docs: {
24
+ description:
25
+ 'A catalogue message never says "Something went wrong", "Unable to", "Heads up", "please" or "successfully".',
26
+ },
27
+ schema: [],
28
+ messages: {
29
+ "stock-phrase":
30
+ 'A catalogue message does not say "{{phrase}}": name what happened to which record and what the person can do, in the active voice ("Couldn\'t pause Discord. The Gateway didn\'t answer."), with no please and no "successfully".',
31
+ },
32
+ },
33
+ create(context) {
34
+ const filename = context.filename.replaceAll("\\", "/");
35
+ if (!CATALOGUE_FILE.test(filename) || TEST_FILE.test(filename)) return {};
36
+
37
+ function check(node, text) {
38
+ if (text === null) return;
39
+ for (const [phrase, pattern] of PHRASES) {
40
+ if (pattern.test(text))
41
+ context.report({ node, messageId: "stock-phrase", data: { phrase } });
42
+ }
43
+ }
44
+
45
+ return {
46
+ Literal(node) {
47
+ if (node.parent.type === "ImportDeclaration" || node.parent.type === "ExportAllDeclaration")
48
+ return;
49
+ check(node, literalText(node));
50
+ },
51
+ TemplateElement(node) {
52
+ check(node, node.value.cooked);
53
+ },
54
+ };
55
+ },
56
+ };
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Standard tool checked first: a `no-restricted-syntax` selector can match a
3
+ * `Field` descendant of a `Tooltip` by element name, but not that both are
4
+ * imports from the design system, nor reach a field named in the `render`
5
+ * element of a trigger, so it would also refuse a product's own `Input`.
6
+ */
7
+ import { renderedImports, walk } from "./rendered-import.js";
8
+
9
+ const WRAPPERS = new Set(["Tooltip", "TooltipTrigger", "HoverCard", "HoverCardTrigger"]);
10
+ const POPUPS = new Set(["TooltipContent", "HoverCardContent"]);
11
+ const FIELDS = new Set([
12
+ "Input",
13
+ "Textarea",
14
+ "ClearableInput",
15
+ "CollectionSearch",
16
+ "Select",
17
+ "SelectTrigger",
18
+ "NativeSelect",
19
+ "Combobox",
20
+ "ComboboxInput",
21
+ "Checkbox",
22
+ "Switch",
23
+ "Label",
24
+ "FieldLabel",
25
+ "SettingsField",
26
+ ]);
27
+
28
+ const FROM_DESIGN_SYSTEM = /^(@nadicodeai\/ui(\/|$)|@\/|\.)/;
29
+
30
+ export const noTooltipAroundLabelledField = {
31
+ meta: {
32
+ type: "problem",
33
+ docs: {
34
+ description:
35
+ "A Tooltip or HoverCard never wraps a field: put the help on an icon button beside it.",
36
+ },
37
+ schema: [],
38
+ messages: {
39
+ "field-tooltip":
40
+ "Do not put a Tooltip or HoverCard on a field: its text becomes a second, hidden label. Put the help on an icon button beside the field.",
41
+ },
42
+ },
43
+ create(context) {
44
+ const importOf = renderedImports(context);
45
+ const exportOf = (elementName) => {
46
+ const imported = importOf(elementName);
47
+ return imported && FROM_DESIGN_SYSTEM.test(imported.source) ? imported.name : null;
48
+ };
49
+
50
+ function wrapsAField(element) {
51
+ let found = false;
52
+ walk(element, context.sourceCode.visitorKeys, (child) => {
53
+ if (child.type !== "JSXElement") return true;
54
+ const name = exportOf(child.openingElement.name);
55
+ if (POPUPS.has(name)) return false;
56
+ if (!FIELDS.has(name)) return true;
57
+ found = true;
58
+ return "stop";
59
+ });
60
+ return found;
61
+ }
62
+
63
+ return {
64
+ JSXElement(node) {
65
+ if (!WRAPPERS.has(exportOf(node.openingElement.name))) return;
66
+ if (wrapsAField(node)) {
67
+ context.report({ node: node.openingElement, messageId: "field-tooltip" });
68
+ }
69
+ },
70
+ };
71
+ },
72
+ };
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Standard tool checked first: a `no-restricted-syntax` selector can match a
3
+ * `strong` whose own className holds a weight class, but cannot ask whether some
4
+ * element above it carries a type role, so it would refuse every weighted
5
+ * `<strong>` or none. This rule reads both classNames, ancestors included, in
6
+ * one file.
7
+ */
8
+ import { openingElementClassUtilities } from "./jsx-class-utility.js";
9
+
10
+ const STRONG_TAGS = new Set(["strong", "b"]);
11
+ const WEIGHT_CLASS = /^font-(medium|semibold|bold)$/;
12
+ const TYPE_ROLE_CLASS = /^(nc-type-|text-(display-|heading-|body-|label|caption))/;
13
+
14
+ const baseUtility = (utility) => utility.slice(utility.lastIndexOf(":") + 1).replace(/^!/, "");
15
+
16
+ const hasUtility = (element, context, pattern) =>
17
+ openingElementClassUtilities(element, context).some((utility) =>
18
+ pattern.test(baseUtility(utility)),
19
+ );
20
+
21
+ function hasTypeRoleAncestor(element, context) {
22
+ for (let ancestor = element.parent?.parent; ancestor; ancestor = ancestor.parent) {
23
+ if (
24
+ ancestor.type === "JSXElement" &&
25
+ hasUtility(ancestor.openingElement, context, TYPE_ROLE_CLASS)
26
+ ) {
27
+ return true;
28
+ }
29
+ }
30
+ return false;
31
+ }
32
+
33
+ export const noWeightClassOnStrongInTypeRole = {
34
+ meta: {
35
+ type: "problem",
36
+ docs: {
37
+ description:
38
+ "A type role sets the weight of a nested <strong>; the element carries no weight class.",
39
+ },
40
+ schema: [],
41
+ messages: {
42
+ "weight-on-strong":
43
+ "The type role sets the weight of a nested <strong>: 550 in copy, 500 in labels and headings. Remove the font-weight class from the <strong>.",
44
+ },
45
+ },
46
+ create(context) {
47
+ return {
48
+ JSXOpeningElement(node) {
49
+ if (node.name.type !== "JSXIdentifier" || !STRONG_TAGS.has(node.name.name)) return;
50
+ if (!hasUtility(node, context, WEIGHT_CLASS)) return;
51
+ if (hasTypeRoleAncestor(node, context)) {
52
+ context.report({ node, messageId: "weight-on-strong" });
53
+ }
54
+ },
55
+ };
56
+ },
57
+ };
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Standard tool checked first: a `no-restricted-syntax` descendant selector
3
+ * matches by element name, so it cannot tell the package's
4
+ * `DropdownMenuSub` from a local component of the same name or follow a
5
+ * renamed import.
6
+ */
7
+ import { renderedImports } from "./rendered-import.js";
8
+
9
+ const SUBMENUS = new Set(["DropdownMenuSub", "ContextMenuSub", "MenubarSub"]);
10
+ const FROM_DESIGN_SYSTEM = /^(@nadicodeai\/ui(\/|$)|@\/|\.)/;
11
+
12
+ export const oneSubmenuLevel = {
13
+ meta: {
14
+ type: "problem",
15
+ docs: { description: "A menu has one level of submenu, never a submenu inside a submenu." },
16
+ schema: [],
17
+ messages: {
18
+ "nested-submenu":
19
+ "A menu opens one submenu deep. A third level hides commands behind a pointer path that is easy to lose: flatten the inner submenu into a group of the first, or move it to its own menu.",
20
+ },
21
+ },
22
+ create(context) {
23
+ const importOf = renderedImports(context);
24
+ const isSubmenu = (element) => {
25
+ const imported = importOf(element.openingElement.name);
26
+ return (
27
+ imported !== null && SUBMENUS.has(imported.name) && FROM_DESIGN_SYSTEM.test(imported.source)
28
+ );
29
+ };
30
+
31
+ return {
32
+ JSXElement(node) {
33
+ if (!isSubmenu(node)) return;
34
+ for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
35
+ if (ancestor.type === "JSXElement" && isSubmenu(ancestor)) {
36
+ context.report({ node: node.openingElement, messageId: "nested-submenu" });
37
+ return;
38
+ }
39
+ }
40
+ },
41
+ };
42
+ },
43
+ };
@@ -0,0 +1,91 @@
1
+ /*
2
+ * Standard tool checked first: `no-restricted-syntax` selectors match one node
3
+ * and its ancestors, but whether two calls can both run is a question about
4
+ * how their paths split (if/else, ?:, try/catch, switch cases, an early
5
+ * return), which no selector can ask.
6
+ */
7
+ const TOAST_CALLS = new Set(["notify", "notifyError", "showMessageToast"]);
8
+ const EXITS = new Set(["ReturnStatement", "ThrowStatement"]);
9
+ const STATEMENT_LISTS = new Set(["BlockStatement", "SwitchCase", "Program", "StaticBlock"]);
10
+
11
+ const calleeName = (callee) => {
12
+ if (callee.type === "Identifier") return callee.name;
13
+ if (callee.type === "MemberExpression" && !callee.computed) return callee.property.name;
14
+ return null;
15
+ };
16
+
17
+ const isToastCall = (node) => TOAST_CALLS.has(calleeName(node.callee));
18
+
19
+ const chainOf = (node) => {
20
+ const chain = [];
21
+ for (let current = node; current; current = current.parent) chain.push(current);
22
+ return chain;
23
+ };
24
+
25
+ const branchesOf = (split) => {
26
+ if (split.type === "IfStatement") return [split.consequent, split.alternate];
27
+ if (split.type === "ConditionalExpression") return [split.consequent, split.alternate];
28
+ if (split.type === "TryStatement") return [split.block, split.handler];
29
+ if (split.type === "SwitchStatement") return split.cases;
30
+ return [];
31
+ };
32
+
33
+ const onDifferentBranches = (split, first, second) => {
34
+ const branches = branchesOf(split);
35
+ return branches.includes(first) && branches.includes(second) && first !== second;
36
+ };
37
+
38
+ const leavesBefore = (below, split) =>
39
+ below.some((node) => {
40
+ if (EXITS.has(node.type)) return true;
41
+ const list = node.parent;
42
+ if (!STATEMENT_LISTS.has(list.type) || list === split) return false;
43
+ const siblings = list.type === "SwitchCase" ? list.consequent : list.body;
44
+ return siblings.slice(siblings.indexOf(node) + 1).some((next) => EXITS.has(next.type));
45
+ });
46
+
47
+ function runsAfter(earlier, later) {
48
+ const laterChain = chainOf(later);
49
+ const earlierChain = chainOf(earlier);
50
+ const meeting = earlierChain.findIndex((node) => laterChain.includes(node));
51
+ const split = earlierChain[meeting];
52
+ const earlierBelow = earlierChain.slice(0, meeting);
53
+ const laterSide = laterChain[laterChain.indexOf(split) - 1];
54
+ if (onDifferentBranches(split, earlierBelow.at(-1), laterSide)) return false;
55
+ return !leavesBefore(earlierBelow, split);
56
+ }
57
+
58
+ export const oneToastPerFlow = {
59
+ meta: {
60
+ type: "problem",
61
+ docs: {
62
+ description:
63
+ "A flow raises one toast when it ends, never one per step: a success and a failure on separate paths are fine.",
64
+ },
65
+ schema: [],
66
+ messages: {
67
+ "toast-per-step": "Raise one toast when the flow ends, not one per step.",
68
+ },
69
+ },
70
+ create(context) {
71
+ const scopes = [[]];
72
+
73
+ function closeScope() {
74
+ const calls = scopes.pop();
75
+ calls.forEach((call, index) => {
76
+ if (calls.slice(0, index).some((earlier) => runsAfter(earlier, call))) {
77
+ context.report({ node: call, messageId: "toast-per-step" });
78
+ }
79
+ });
80
+ }
81
+
82
+ return {
83
+ ":function": () => scopes.push([]),
84
+ ":function:exit": closeScope,
85
+ "Program:exit": closeScope,
86
+ CallExpression(node) {
87
+ if (isToastCall(node)) scopes.at(-1).push(node);
88
+ },
89
+ };
90
+ },
91
+ };