@elabs-ai/components-ui 4.0.0 → 4.2.0

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 (339) hide show
  1. package/README.md +10 -8
  2. package/dist/chunk-FCH4ZN6G.js +57 -0
  3. package/dist/chunk-FCH4ZN6G.js.map +1 -0
  4. package/dist/form.d.ts +28 -0
  5. package/dist/form.js +123 -0
  6. package/dist/form.js.map +1 -0
  7. package/dist/index.d.ts +2597 -188
  8. package/dist/index.js +12855 -3578
  9. package/dist/index.js.map +1 -1
  10. package/dist/lib/cn.js +10 -1
  11. package/dist/lib/cn.js.map +1 -1
  12. package/package.json +21 -7
  13. package/src/__contract__/attribution-panel.contract.test.tsx +49 -0
  14. package/src/__contract__/badge.contract.test.tsx +49 -0
  15. package/src/__contract__/bounded-number.contract.test.tsx +49 -0
  16. package/src/__contract__/button.contract.test.tsx +49 -0
  17. package/src/__contract__/color-picker.contract.test.tsx +49 -0
  18. package/src/__contract__/combobox.contract.test.tsx +49 -0
  19. package/src/__contract__/command-trigger.contract.test.tsx +49 -0
  20. package/src/__contract__/copyable-value.contract.test.tsx +49 -0
  21. package/src/__contract__/date-picker.contract.test.tsx +49 -0
  22. package/src/__contract__/date-range-picker.contract.test.tsx +49 -0
  23. package/src/__contract__/empty-state.contract.test.tsx +49 -0
  24. package/src/__contract__/error-state.contract.test.tsx +49 -0
  25. package/src/__contract__/icon-button.contract.test.tsx +49 -0
  26. package/src/__contract__/input.contract.test.tsx +49 -0
  27. package/src/__contract__/key-value-editor.contract.test.tsx +49 -0
  28. package/src/__contract__/list-editor.contract.test.tsx +49 -0
  29. package/src/__contract__/loading-state.contract.test.tsx +49 -0
  30. package/src/__contract__/metric-card.contract.test.tsx +49 -0
  31. package/src/__contract__/model-picker.contract.test.tsx +49 -0
  32. package/src/__contract__/nav-notifications.contract.test.tsx +49 -0
  33. package/src/__contract__/number-input.contract.test.tsx +49 -0
  34. package/src/__contract__/rating.contract.test.tsx +49 -0
  35. package/src/__contract__/schema-form.contract.test.tsx +49 -0
  36. package/src/__contract__/section-header.contract.test.tsx +49 -0
  37. package/src/__contract__/segmented-field.contract.test.tsx +49 -0
  38. package/src/__contract__/slider-number.contract.test.tsx +49 -0
  39. package/src/__contract__/status-badge.contract.test.tsx +49 -0
  40. package/src/__contract__/tag-input.contract.test.tsx +49 -0
  41. package/src/__contract__/text.contract.test.tsx +49 -0
  42. package/src/__contract__/textarea.contract.test.tsx +49 -0
  43. package/src/__contract__/timeline.contract.test.tsx +49 -0
  44. package/src/__contract__/toggle.contract.test.tsx +49 -0
  45. package/src/__contract__/transfer.contract.test.tsx +49 -0
  46. package/src/__contract__/tree-select.contract.test.tsx +49 -0
  47. package/src/__contract__/tree.contract.test.tsx +49 -0
  48. package/src/__contract__/virtual-select.contract.test.tsx +49 -0
  49. package/src/__contract__/workspace-picker.contract.test.tsx +49 -0
  50. package/src/_peer-deps.test.ts +59 -0
  51. package/src/blocks-comparison-table.stories.tsx +2 -2
  52. package/src/components/accordion/accordion.tsx +13 -4
  53. package/src/components/advanced-group/advanced-group.tsx +1 -1
  54. package/src/components/alert/alert.tsx +15 -4
  55. package/src/components/alert-dialog/alert-dialog.test.tsx +32 -0
  56. package/src/components/alert-dialog/alert-dialog.tsx +28 -6
  57. package/src/components/app-shell/app-shell.stories.tsx +44 -2
  58. package/src/components/app-shell/app-shell.test.tsx +99 -0
  59. package/src/components/app-shell/app-shell.tsx +56 -4
  60. package/src/components/app-sidebar/app-sidebar.stories.tsx +9 -1
  61. package/src/components/attribution-panel/attribution-panel.tsx +3 -1
  62. package/src/components/attribution-panel/attributions.generated.ts +83 -79
  63. package/src/components/avatar/avatar.tsx +4 -1
  64. package/src/components/badge/badge.stories.tsx +8 -0
  65. package/src/components/badge/badge.test.tsx +8 -0
  66. package/src/components/badge/badge.tsx +15 -5
  67. package/src/components/bento-grid/bento-grid.test.tsx +24 -3
  68. package/src/components/bento-grid/bento-grid.tsx +11 -1
  69. package/src/components/bounded-number/bounded-number.test.tsx +1 -1
  70. package/src/components/bounded-number/bounded-number.tsx +78 -75
  71. package/src/components/breadcrumb/breadcrumb.stories.tsx +38 -0
  72. package/src/components/breadcrumb/breadcrumb.test.tsx +24 -1
  73. package/src/components/breadcrumb/breadcrumb.tsx +10 -4
  74. package/src/components/button/button.stories.tsx +116 -8
  75. package/src/components/button/button.tsx +18 -12
  76. package/src/components/button-group/button-group.tsx +1 -1
  77. package/src/components/calendar/calendar.tsx +3 -2
  78. package/src/components/card/card.stories.tsx +11 -6
  79. package/src/components/card/card.test.tsx +24 -2
  80. package/src/components/card/card.tsx +48 -7
  81. package/src/components/carousel/carousel.test.tsx +169 -0
  82. package/src/components/carousel/carousel.tsx +93 -32
  83. package/src/components/change-review/change-review.stories.tsx +145 -1
  84. package/src/components/change-review/change-review.test.tsx +143 -0
  85. package/src/components/change-review/change-review.tsx +214 -24
  86. package/src/components/checkbox/checkbox.tsx +2 -1
  87. package/src/components/collapsible-panel/use-collapsible-panel.ts +0 -3
  88. package/src/components/color-picker/color-picker.tsx +22 -15
  89. package/src/components/combobox/combobox.stories.tsx +10 -0
  90. package/src/components/combobox/combobox.test.tsx +54 -0
  91. package/src/components/combobox/combobox.tsx +25 -11
  92. package/src/components/command/command.stories.tsx +16 -6
  93. package/src/components/command/command.test.tsx +88 -0
  94. package/src/components/command/command.tsx +38 -13
  95. package/src/components/command/index.ts +1 -0
  96. package/src/components/command-trigger/command-trigger.stories.tsx +39 -0
  97. package/src/components/command-trigger/command-trigger.test.tsx +18 -0
  98. package/src/components/command-trigger/command-trigger.tsx +70 -0
  99. package/src/components/command-trigger/index.ts +1 -0
  100. package/src/components/context-menu/context-menu.tsx +16 -7
  101. package/src/components/context-rail/context-rail.stories.tsx +285 -0
  102. package/src/components/context-rail/context-rail.test.tsx +263 -0
  103. package/src/components/context-rail/context-rail.tsx +678 -0
  104. package/src/components/context-rail/index.ts +1 -0
  105. package/src/components/copyable-value/copyable-value.stories.tsx +10 -0
  106. package/src/components/copyable-value/copyable-value.test.tsx +28 -1
  107. package/src/components/copyable-value/copyable-value.tsx +13 -2
  108. package/src/components/date-picker/date-picker.stories.tsx +9 -0
  109. package/src/components/date-picker/date-picker.test.tsx +52 -0
  110. package/src/components/date-picker/date-picker.tsx +13 -15
  111. package/src/components/date-range-picker/date-range-picker.stories.tsx +9 -0
  112. package/src/components/date-range-picker/date-range-picker.test.tsx +76 -1
  113. package/src/components/date-range-picker/date-range-picker.tsx +39 -28
  114. package/src/components/descriptions/descriptions.tsx +1 -1
  115. package/src/components/dialog/dialog.test.tsx +8 -3
  116. package/src/components/dialog/dialog.tsx +14 -6
  117. package/src/components/drawer/drawer.tsx +23 -6
  118. package/src/components/dropdown-menu/dropdown-menu.stories.tsx +1 -1
  119. package/src/components/dropdown-menu/dropdown-menu.tsx +4 -4
  120. package/src/components/empty-state/empty-state.test.tsx +26 -0
  121. package/src/components/empty-state/empty-state.tsx +6 -1
  122. package/src/components/expand-dialog/expand-dialog.tsx +1 -2
  123. package/src/components/field/field-context.ts +59 -0
  124. package/src/components/field/field.stories.tsx +142 -0
  125. package/src/components/field/field.test.tsx +415 -0
  126. package/src/components/field/field.tsx +342 -0
  127. package/src/components/field/index.ts +9 -0
  128. package/src/components/field-row/field-row.stories.tsx +85 -1
  129. package/src/components/field-row/field-row.test.tsx +145 -0
  130. package/src/components/field-row/field-row.tsx +50 -6
  131. package/src/components/file-upload/file-upload.stories.tsx +16 -0
  132. package/src/components/file-upload/file-upload.test.tsx +90 -12
  133. package/src/components/file-upload/file-upload.tsx +164 -31
  134. package/src/components/form/form.tsx +8 -3
  135. package/src/components/hover-card/hover-card.tsx +1 -0
  136. package/src/components/icon-button/icon-button.test.tsx +1 -1
  137. package/src/components/icon-button/icon-button.tsx +3 -3
  138. package/src/components/input/input.stories.tsx +121 -0
  139. package/src/components/input/input.test.tsx +13 -0
  140. package/src/components/input/input.tsx +8 -4
  141. package/src/components/input-group/input-group.stories.tsx +74 -0
  142. package/src/components/input-group/input-group.tsx +18 -9
  143. package/src/components/input-otp/input-otp.tsx +8 -2
  144. package/src/components/keyboard-shortcuts/index.ts +6 -0
  145. package/src/components/keyboard-shortcuts/keyboard-shortcuts.stories.tsx +177 -0
  146. package/src/components/keyboard-shortcuts/keyboard-shortcuts.test.tsx +73 -0
  147. package/src/components/keyboard-shortcuts/keyboard-shortcuts.tsx +203 -0
  148. package/src/components/label/label.tsx +1 -1
  149. package/src/components/link-preview/link-preview.tsx +1 -1
  150. package/src/components/list-editor/list-editor.test.tsx +24 -0
  151. package/src/components/list-editor/list-editor.tsx +126 -52
  152. package/src/components/locale-provider/index.ts +6 -1
  153. package/src/components/locale-provider/locale-keys.test.ts +134 -0
  154. package/src/components/locale-provider/locale-provider.stories.tsx +89 -1
  155. package/src/components/locale-provider/locale-provider.test.tsx +257 -1
  156. package/src/components/locale-provider/locale-provider.tsx +63 -8
  157. package/src/components/locale-provider/messages.ts +822 -2
  158. package/src/components/match-highlight/match-highlight.stories.tsx +1 -1
  159. package/src/components/mention-input/mention-input-mirror.stories.tsx +9 -1
  160. package/src/components/mention-input/mention-input.stories.tsx +3 -3
  161. package/src/components/mention-input/mention-input.test.tsx +51 -1
  162. package/src/components/mention-input/mention-input.tsx +66 -46
  163. package/src/components/mention-input/mention-value.ts +8 -2
  164. package/src/components/menubar/menubar.tsx +16 -6
  165. package/src/components/metric-card/metric-card.stories.tsx +5 -3
  166. package/src/components/metric-card/metric-card.tsx +21 -2
  167. package/src/components/model-picker/model-picker.stories.tsx +63 -3
  168. package/src/components/model-picker/model-picker.test.tsx +63 -0
  169. package/src/components/model-picker/model-picker.tsx +62 -36
  170. package/src/components/nav-main/nav-main.tsx +8 -4
  171. package/src/components/nav-notifications/nav-notifications.stories.tsx +110 -0
  172. package/src/components/nav-notifications/nav-notifications.test.tsx +11 -0
  173. package/src/components/nav-notifications/nav-notifications.tsx +67 -9
  174. package/src/components/nav-user/nav-user.tsx +5 -5
  175. package/src/components/navigation-menu/navigation-menu.stories.tsx +22 -0
  176. package/src/components/navigation-menu/navigation-menu.test.tsx +174 -0
  177. package/src/components/navigation-menu/navigation-menu.tsx +204 -15
  178. package/src/components/number-input/number-input.stories.tsx +7 -3
  179. package/src/components/number-input/number-input.test.tsx +47 -0
  180. package/src/components/number-input/number-input.tsx +65 -24
  181. package/src/components/page-shell/page-shell.stories.tsx +163 -0
  182. package/src/components/page-shell/page-shell.test.tsx +229 -0
  183. package/src/components/page-shell/page-shell.tsx +108 -25
  184. package/src/components/pagination/pagination.test.tsx +109 -0
  185. package/src/components/pagination/pagination.tsx +27 -19
  186. package/src/components/popover/popover.tsx +1 -0
  187. package/src/components/progress/progress.tsx +2 -0
  188. package/src/components/radio-group/radio-group.tsx +1 -1
  189. package/src/components/rating/rating.tsx +3 -1
  190. package/src/components/resizable/resizable.stories.tsx +114 -2
  191. package/src/components/resizable/resizable.test.tsx +76 -0
  192. package/src/components/resizable/resizable.tsx +32 -6
  193. package/src/components/revision-timeline/revision-timeline.stories.tsx +8 -1
  194. package/src/components/revision-timeline/revision-timeline.test.tsx +26 -0
  195. package/src/components/revision-timeline/revision-timeline.tsx +53 -5
  196. package/src/components/schema-form/from-json-schema.test.ts +390 -0
  197. package/src/components/schema-form/from-json-schema.ts +375 -0
  198. package/src/components/schema-form/index.ts +81 -0
  199. package/src/components/schema-form/schema-form-spec.ts +698 -0
  200. package/src/components/schema-form/schema-form-store.ts +506 -0
  201. package/src/components/schema-form/schema-form.stories.tsx +566 -0
  202. package/src/components/schema-form/schema-form.test.tsx +1021 -0
  203. package/src/components/schema-form/schema-form.tsx +1381 -0
  204. package/src/components/section-header/section-header.stories.tsx +37 -0
  205. package/src/components/section-header/section-header.tsx +14 -3
  206. package/src/components/select/select.tsx +13 -7
  207. package/src/components/separator/separator.tsx +1 -0
  208. package/src/components/sheet/sheet.test.tsx +39 -0
  209. package/src/components/sheet/sheet.tsx +40 -9
  210. package/src/components/side-dock/index.ts +1 -0
  211. package/src/components/side-dock/side-dock.stories.tsx +137 -0
  212. package/src/components/side-dock/side-dock.test.tsx +299 -0
  213. package/src/components/side-dock/side-dock.tsx +515 -0
  214. package/src/components/sidebar/index.ts +1 -0
  215. package/src/components/sidebar/sidebar-frame.test.tsx +162 -0
  216. package/src/components/sidebar/sidebar.stories.tsx +421 -1
  217. package/src/components/sidebar/sidebar.test.tsx +71 -2
  218. package/src/components/sidebar/sidebar.tsx +264 -38
  219. package/src/components/skeleton/skeleton.tsx +1 -0
  220. package/src/components/skip-link/index.ts +1 -0
  221. package/src/components/skip-link/skip-link.stories.tsx +106 -0
  222. package/src/components/skip-link/skip-link.test.tsx +20 -0
  223. package/src/components/skip-link/skip-link.tsx +34 -0
  224. package/src/components/slider/slider.tsx +1 -1
  225. package/src/components/slider-number/slider-number.stories.tsx +4 -1
  226. package/src/components/slider-number/slider-number.test.tsx +1 -1
  227. package/src/components/sonner/sonner.tsx +2 -0
  228. package/src/components/spinner/spinner.test.tsx +18 -0
  229. package/src/components/spinner/spinner.tsx +14 -4
  230. package/src/components/split-panel/index.ts +6 -1
  231. package/src/components/split-panel/split-panel.stories.tsx +18 -2
  232. package/src/components/split-panel/split-panel.test.tsx +20 -0
  233. package/src/components/split-panel/split-panel.tsx +28 -8
  234. package/src/components/state-panel/state-panel.stories.tsx +52 -0
  235. package/src/components/state-panel/state-panel.test.tsx +125 -0
  236. package/src/components/state-panel/state-panel.tsx +110 -24
  237. package/src/components/status-badge/status-badge.stories.tsx +8 -0
  238. package/src/components/switch/switch.tsx +3 -1
  239. package/src/components/table/table.stories.tsx +64 -0
  240. package/src/components/table/table.test.tsx +149 -1
  241. package/src/components/table/table.tsx +71 -2
  242. package/src/components/tabs/index.ts +10 -1
  243. package/src/components/tabs/tabs.stories.tsx +48 -0
  244. package/src/components/tabs/tabs.test.tsx +67 -0
  245. package/src/components/tabs/tabs.tsx +176 -72
  246. package/src/components/tag-input/tag-input.tsx +6 -3
  247. package/src/components/team-switcher/team-switcher.tsx +35 -6
  248. package/src/components/textarea/textarea.tsx +2 -2
  249. package/src/components/theme-switcher/theme-switcher.stories.tsx +76 -0
  250. package/src/components/theme-switcher/theme-switcher.test.tsx +182 -0
  251. package/src/components/theme-switcher/theme-switcher.tsx +140 -12
  252. package/src/components/theme-switcher/use-theme-transition.ts +2 -2
  253. package/src/components/timeline/timeline.stories.tsx +27 -0
  254. package/src/components/timeline/timeline.tsx +10 -3
  255. package/src/components/toggle/toggle.tsx +7 -2
  256. package/src/components/toggle-group/toggle-group.tsx +2 -0
  257. package/src/components/toolbar/toolbar.stories.tsx +10 -2
  258. package/src/components/tooltip/tooltip.tsx +2 -1
  259. package/src/components/top-nav/top-nav.tsx +1 -1
  260. package/src/components/transfer/transfer.tsx +35 -30
  261. package/src/components/tree/tree.stories.tsx +2 -2
  262. package/src/components/tree/tree.test.tsx +41 -0
  263. package/src/components/tree/tree.tsx +91 -31
  264. package/src/components/tree/use-tree-keyboard.ts +37 -14
  265. package/src/components/tree-select/tree-select.stories.tsx +9 -0
  266. package/src/components/tree-select/tree-select.test.tsx +5 -0
  267. package/src/components/tree-select/tree-select.tsx +11 -14
  268. package/src/components/typography/prose.test.tsx +3 -2
  269. package/src/components/typography/prose.tsx +3 -3
  270. package/src/components/typography/typography.stories.tsx +228 -0
  271. package/src/components/view-toolbar/view-toolbar.stories.tsx +41 -1
  272. package/src/components/view-toolbar/view-toolbar.test.tsx +33 -0
  273. package/src/components/view-toolbar/view-toolbar.tsx +37 -4
  274. package/src/components/virtual-select/virtual-select.stories.tsx +9 -0
  275. package/src/components/virtual-select/virtual-select.test.tsx +29 -3
  276. package/src/components/virtual-select/virtual-select.tsx +56 -18
  277. package/src/components/wizard/wizard.test.tsx +9 -0
  278. package/src/components/wizard/wizard.tsx +13 -5
  279. package/src/components/workspace-picker/index.ts +3 -0
  280. package/src/components/workspace-picker/workspace-picker-state.ts +50 -0
  281. package/src/components/workspace-picker/workspace-picker.stories.tsx +126 -0
  282. package/src/components/workspace-picker/workspace-picker.test.tsx +207 -0
  283. package/src/components/workspace-picker/workspace-picker.tsx +172 -0
  284. package/src/illustrations/empty-list-illustration.tsx +26 -0
  285. package/src/illustrations/error-illustration.tsx +60 -0
  286. package/src/illustrations/first-run-illustration.tsx +27 -0
  287. package/src/illustrations/illustration-base.tsx +108 -0
  288. package/src/illustrations/illustrations.stories.tsx +94 -0
  289. package/src/illustrations/illustrations.test.tsx +98 -0
  290. package/src/illustrations/index.ts +16 -0
  291. package/src/illustrations/no-access-illustration.tsx +45 -0
  292. package/src/illustrations/no-results-illustration.tsx +46 -0
  293. package/src/illustrations/offline-illustration.tsx +37 -0
  294. package/src/illustrations/success-illustration.tsx +40 -0
  295. package/src/index.ts +80 -2
  296. package/src/lib/agent-event-model.test.ts +12 -0
  297. package/src/lib/agent-event-model.ts +42 -0
  298. package/src/lib/approval-option.test.ts +17 -0
  299. package/src/lib/approval-option.ts +53 -0
  300. package/src/lib/check-result.ts +33 -0
  301. package/src/lib/cn.ts +9 -0
  302. package/src/lib/csv.ts +48 -0
  303. package/src/lib/diff-line.test.ts +36 -0
  304. package/src/lib/diff-line.ts +63 -0
  305. package/src/lib/diff-rows.test.ts +76 -0
  306. package/src/lib/diff-rows.ts +94 -0
  307. package/src/lib/format-duration.test.ts +22 -0
  308. package/src/lib/format-duration.ts +30 -0
  309. package/src/lib/has-renderable-content.test.ts +49 -0
  310. package/src/lib/has-renderable-content.ts +32 -0
  311. package/src/lib/merge-refs.ts +2 -0
  312. package/src/lib/operating-mode.test.ts +36 -0
  313. package/src/lib/operating-mode.ts +81 -0
  314. package/src/lib/optional-peer.ts +59 -0
  315. package/src/lib/session-launch.ts +37 -0
  316. package/src/lib/slash-command.test.ts +44 -0
  317. package/src/lib/slash-command.ts +45 -0
  318. package/src/lib/trigger-query.test.ts +94 -0
  319. package/src/lib/trigger-query.ts +88 -0
  320. package/src/lib/use-controllable-state.ts +47 -0
  321. package/src/lib/use-mobile.test.tsx +47 -0
  322. package/src/lib/use-mobile.ts +34 -12
  323. package/src/motion.stories.tsx +6 -0
  324. package/src/templates-object-detail-hub.stories.tsx +2 -2
  325. package/src/templates-screen-states.stories.tsx +5 -5
  326. package/src/templates-settings.stories.tsx +1 -1
  327. package/src/blocks/sidebar-02/app-sidebar.tsx +0 -160
  328. package/src/blocks/sidebar-02/logo.tsx +0 -18
  329. package/src/blocks/sidebar-02/nav-main.tsx +0 -13
  330. package/src/blocks/sidebar-02/nav-notifications.tsx +0 -7
  331. package/src/blocks/sidebar-02/sidebar-02.stories.tsx +0 -23
  332. package/src/blocks/sidebar-02/team-switcher.tsx +0 -7
  333. package/src/blocks/sidebar-04/app-sidebar.tsx +0 -236
  334. package/src/blocks/sidebar-04/mail-context.tsx +0 -29
  335. package/src/blocks/sidebar-04/nav-user.tsx +0 -6
  336. package/src/blocks/sidebar-04/sidebar-04.stories.tsx +0 -150
  337. package/src/blocks/sidebar-05/app-sidebar.tsx +0 -375
  338. package/src/blocks/sidebar-05/sidebar-05.stories.tsx +0 -18
  339. package/src/blocks/sidebar-05/team-switcher.tsx +0 -6
package/dist/lib/cn.js CHANGED
@@ -7,7 +7,16 @@ var twMerge = extendTailwindMerge({
7
7
  classGroups: {
8
8
  "font-size": [{ text: TEXT_ROLES }],
9
9
  // `font-display` is the display-face seam (sibling of font-mono, #187).
10
- "font-family": [{ font: ["display"] }]
10
+ "font-family": [{ font: ["display"] }],
11
+ // Theme-driven control/table knobs (themes.css § CONTROL UTILITIES and the
12
+ // `@theme inline` bridge) — so a caller's `h-8` / `rounded-none` /
13
+ // `font-bold` / `shadow-none` still replaces the token default.
14
+ "font-weight": [{ font: ["control", "table-header"] }],
15
+ rounded: [{ rounded: ["control"] }],
16
+ shadow: [{ shadow: ["input"] }],
17
+ h: [{ h: ["control", "control-sm", "control-lg", "header"] }],
18
+ size: [{ size: ["control", "control-sm", "control-lg"] }],
19
+ "min-w": [{ "min-w": ["control", "control-sm", "control-lg"] }]
11
20
  }
12
21
  }
13
22
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * The semantic type roles (`--text-<role>` tokens → `text-<role>` utilities, #187).\n * tailwind-merge doesn't know custom theme keys, so without registration it\n * classifies `text-title` as a text COLOR — and `cn(\"text-kpi\", \"text-foreground\")`\n * would silently drop the role. Registering the roles in the `font-size` class\n * group makes role-vs-role and role-vs-raw-size conflicts resolve correctly while\n * keeping role + color independent.\n */\nconst TEXT_ROLES = [\"display\", \"title\", \"subtitle\", \"body\", \"caption\", \"meta\", \"kpi\", \"code\"];\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n \"font-size\": [{ text: TEXT_ROLES }],\n // `font-display` is the display-face seam (sibling of font-mono, #187).\n \"font-family\": [{ font: [\"display\"] }],\n },\n },\n});\n\n/**\n * Merge class names with conflict resolution. `clsx` handles conditionals;\n * `tailwind-merge` ensures later Tailwind utilities win (e.g. `p-2 p-4` -> `p-4`).\n * Use this in every component that accepts a `className` prop.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAAS,YAA6B;AACtC,SAAS,2BAA2B;AAUpC,IAAM,aAAa,CAAC,WAAW,SAAS,YAAY,QAAQ,WAAW,QAAQ,OAAO,MAAM;AAE5F,IAAM,UAAU,oBAAoB;AAAA,EAClC,QAAQ;AAAA,IACN,aAAa;AAAA,MACX,aAAa,CAAC,EAAE,MAAM,WAAW,CAAC;AAAA;AAAA,MAElC,eAAe,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;AAAA,IACvC;AAAA,EACF;AACF,CAAC;AAOM,SAAS,MAAM,QAA8B;AAClD,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/cn.ts"],"sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { extendTailwindMerge } from \"tailwind-merge\";\n\n/**\n * The semantic type roles (`--text-<role>` tokens → `text-<role>` utilities, #187).\n * tailwind-merge doesn't know custom theme keys, so without registration it\n * classifies `text-title` as a text COLOR — and `cn(\"text-kpi\", \"text-foreground\")`\n * would silently drop the role. Registering the roles in the `font-size` class\n * group makes role-vs-role and role-vs-raw-size conflicts resolve correctly while\n * keeping role + color independent.\n */\nconst TEXT_ROLES = [\"display\", \"title\", \"subtitle\", \"body\", \"caption\", \"meta\", \"kpi\", \"code\"];\n\nconst twMerge = extendTailwindMerge({\n extend: {\n classGroups: {\n \"font-size\": [{ text: TEXT_ROLES }],\n // `font-display` is the display-face seam (sibling of font-mono, #187).\n \"font-family\": [{ font: [\"display\"] }],\n // Theme-driven control/table knobs (themes.css § CONTROL UTILITIES and the\n // `@theme inline` bridge) — so a caller's `h-8` / `rounded-none` /\n // `font-bold` / `shadow-none` still replaces the token default.\n \"font-weight\": [{ font: [\"control\", \"table-header\"] }],\n rounded: [{ rounded: [\"control\"] }],\n shadow: [{ shadow: [\"input\"] }],\n h: [{ h: [\"control\", \"control-sm\", \"control-lg\", \"header\"] }],\n size: [{ size: [\"control\", \"control-sm\", \"control-lg\"] }],\n \"min-w\": [{ \"min-w\": [\"control\", \"control-sm\", \"control-lg\"] }],\n },\n },\n});\n\n/**\n * Merge class names with conflict resolution. `clsx` handles conditionals;\n * `tailwind-merge` ensures later Tailwind utilities win (e.g. `p-2 p-4` -> `p-4`).\n * Use this in every component that accepts a `className` prop.\n */\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";AAAA,SAAS,YAA6B;AACtC,SAAS,2BAA2B;AAUpC,IAAM,aAAa,CAAC,WAAW,SAAS,YAAY,QAAQ,WAAW,QAAQ,OAAO,MAAM;AAE5F,IAAM,UAAU,oBAAoB;AAAA,EAClC,QAAQ;AAAA,IACN,aAAa;AAAA,MACX,aAAa,CAAC,EAAE,MAAM,WAAW,CAAC;AAAA;AAAA,MAElC,eAAe,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;AAAA;AAAA;AAAA;AAAA,MAIrC,eAAe,CAAC,EAAE,MAAM,CAAC,WAAW,cAAc,EAAE,CAAC;AAAA,MACrD,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC;AAAA,MAClC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;AAAA,MAC9B,GAAG,CAAC,EAAE,GAAG,CAAC,WAAW,cAAc,cAAc,QAAQ,EAAE,CAAC;AAAA,MAC5D,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,cAAc,YAAY,EAAE,CAAC;AAAA,MACxD,SAAS,CAAC,EAAE,SAAS,CAAC,WAAW,cAAc,YAAY,EAAE,CAAC;AAAA,IAChE;AAAA,EACF;AACF,CAAC;AAOM,SAAS,MAAM,QAA8B;AAClD,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elabs-ai/components-ui",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,6 +21,10 @@
21
21
  "./lib/cn": {
22
22
  "types": "./dist/lib/cn.d.ts",
23
23
  "default": "./dist/lib/cn.js"
24
+ },
25
+ "./form": {
26
+ "types": "./dist/form.d.ts",
27
+ "default": "./dist/form.js"
24
28
  }
25
29
  },
26
30
  "publishConfig": {
@@ -28,7 +32,6 @@
28
32
  "registry": "https://registry.npmjs.org/"
29
33
  },
30
34
  "dependencies": {
31
- "@hookform/resolvers": "^3.9.1",
32
35
  "@radix-ui/react-accordion": "^1.2.2",
33
36
  "@radix-ui/react-alert-dialog": "^1.1.4",
34
37
  "@radix-ui/react-aspect-ratio": "^1.1.1",
@@ -65,19 +68,28 @@
65
68
  "input-otp": "^1.4.1",
66
69
  "lucide-react": "^0.577.0",
67
70
  "react-day-picker": "^9.4.4",
68
- "react-hook-form": "^7.54.2",
69
71
  "react-resizable-panels": "^2.1.7",
70
72
  "sonner": "^1.7.1",
71
73
  "tailwind-merge": "^2.6.0",
72
- "vaul": "^1.1.2",
73
- "zod": "^3.24.1"
74
+ "vaul": "^1.1.2"
74
75
  },
75
76
  "peerDependencies": {
77
+ "@hookform/resolvers": "^3.9.1",
76
78
  "react": "^18.2.0 || ^19.0.0",
77
79
  "react-dom": "^18.2.0 || ^19.0.0",
78
- "@elabs-ai/components-tokens": "4.0.0"
80
+ "react-hook-form": "^7.54.2",
81
+ "@elabs-ai/components-tokens": "4.2.0"
82
+ },
83
+ "peerDependenciesMeta": {
84
+ "@hookform/resolvers": {
85
+ "optional": true
86
+ },
87
+ "react-hook-form": {
88
+ "optional": true
89
+ }
79
90
  },
80
91
  "devDependencies": {
92
+ "@hookform/resolvers": "^3.9.1",
81
93
  "@testing-library/jest-dom": "^6.6.3",
82
94
  "@testing-library/react": "^16.1.0",
83
95
  "@testing-library/user-event": "^14.5.2",
@@ -88,12 +100,14 @@
88
100
  "jsdom": "^25.0.1",
89
101
  "react": "^19.0.0",
90
102
  "react-dom": "^19.0.0",
103
+ "react-hook-form": "^7.54.2",
91
104
  "tsup": "^8.3.5",
92
105
  "typescript": "^5.7.3",
93
106
  "vitest": "^3.0.2",
107
+ "zod": "^3.24.1",
94
108
  "@elabs-ai/components-eslint-config": "0.1.0",
95
109
  "@elabs-ai/components-typescript-config": "0.1.0",
96
- "@elabs-ai/components-tokens": "4.0.0"
110
+ "@elabs-ai/components-tokens": "4.2.0"
97
111
  },
98
112
  "scripts": {
99
113
  "build": "rm -rf dist && tsup",
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for AttributionPanel (`packages/ui/src/components/attribution-panel/attribution-panel.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/attribution-panel/attribution-panel.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/attribution-panel/attribution-panel.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `core-attributionpanel--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("AttributionPanel contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="attribution-panel" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="attribution-panel"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for Badge (`packages/ui/src/components/badge/badge.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/badge/badge.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/badge/badge.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `core-badge--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("Badge contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="badge" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="badge"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for BoundedNumber (`packages/ui/src/components/bounded-number/bounded-number.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/bounded-number/bounded-number.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/bounded-number/bounded-number.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `forms-boundednumber--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("BoundedNumber contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="bounded-number" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="bounded-number"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for Button (`packages/ui/src/components/button/button.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/button/button.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/button/button.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `core-button--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("Button contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="button" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="button"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for ColorPicker (`packages/ui/src/components/color-picker/color-picker.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/color-picker/color-picker.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/color-picker/color-picker.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `forms-colorpicker--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("ColorPicker contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="color-picker" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="color-picker"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for Combobox (`packages/ui/src/components/combobox/combobox.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/combobox/combobox.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/combobox/combobox.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `forms-combobox--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("Combobox contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="combobox" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="combobox"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for CommandTrigger (`packages/ui/src/components/command-trigger/command-trigger.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/command-trigger/command-trigger.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/command-trigger/command-trigger.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `navigation-commandtrigger--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("CommandTrigger contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="command-trigger" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="command-trigger"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for CopyableValue (`packages/ui/src/components/copyable-value/copyable-value.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/copyable-value/copyable-value.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/copyable-value/copyable-value.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `display-copyablevalue--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("CopyableValue contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="copyable-value" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="copyable-value"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for DatePicker (`packages/ui/src/components/date-picker/date-picker.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/date-picker/date-picker.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/date-picker/date-picker.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `forms-datepicker--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("DatePicker contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="date-picker" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="date-picker"]')).not.toBeNull();
48
+ });
49
+ });
@@ -0,0 +1,49 @@
1
+ // GENERATED by scripts/gen-contract-tests.mjs — do not edit; re-run the generator instead.
2
+ /**
3
+ * Contract probe for DateRangePicker (`packages/ui/src/components/date-range-picker/date-range-picker.tsx`), derived from its
4
+ * `Default` story (packages/ui/src/components/date-range-picker/date-range-picker.stories.tsx). See scripts/gen-contract-tests.mjs.
5
+ */
6
+ import { describe, it, expect, afterEach } from "vitest";
7
+ import { render, cleanup } from "@testing-library/react";
8
+ import { createRef } from "react";
9
+ import * as stories from "../components/date-range-picker/date-range-picker.stories";
10
+ import knownFailuresJson from "../../../../scripts/check/contract-known-failures.json";
11
+
12
+ afterEach(cleanup);
13
+
14
+ // Every component here has its own prop/ref/element shape; a generated probe
15
+ // stays generic on purpose (loosely typed, not untyped — see
16
+ // scripts/gen-contract-tests.mjs) rather than re-deriving each one.
17
+ const KNOWN_FAILURES: Record<string, string> = knownFailuresJson;
18
+ const meta = stories.default as { component?: unknown; args?: Record<string, unknown> };
19
+ const Default = (stories as { Default?: { args?: Record<string, unknown> } }).Default;
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- probe target; see comment above
21
+ const Component = meta.component as any;
22
+ const args = { ...(meta.args ?? {}), ...(Default?.args ?? {}) };
23
+ const isForwardRefComponent = Component?.["$$typeof"] === Symbol.for("react.forward_ref");
24
+
25
+ /** Wrap a known, tracked failure in `it.fails` so fixing it forces the key's removal. */
26
+ function contractIt(assertion: string, name: string, fn: () => void) {
27
+ const key = `forms-daterangepicker--default|jsdom|jsdom|${assertion}`;
28
+ const reason = KNOWN_FAILURES[key];
29
+ if (reason) return it.fails(`${name} (known failure: ${reason})`, fn);
30
+ return it(name, fn);
31
+ }
32
+
33
+ describe("DateRangePicker contract", () => {
34
+ it.skipIf(!isForwardRefComponent)("forwards a ref to a DOM element", () => {
35
+ const ref = createRef<Element>();
36
+ render(<Component {...args} ref={ref} />);
37
+ expect(ref.current).toBeInstanceOf(Element);
38
+ });
39
+
40
+ contractIt("className", "merges a caller className onto the root", () => {
41
+ const { container } = render(<Component {...args} className="contract-probe" />);
42
+ expect(container.querySelector(".contract-probe")).not.toBeNull();
43
+ });
44
+
45
+ contractIt("data-slot", 'exposes data-slot="date-range-picker" on its root', () => {
46
+ const { container } = render(<Component {...args} />);
47
+ expect(container.querySelector('[data-slot="date-range-picker"]')).not.toBeNull();
48
+ });
49
+ });