tembro 2.0.5 → 2.1.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 (381) hide show
  1. package/dist/components/calendar/calendar.cjs +1 -1
  2. package/dist/components/calendar/calendar.d.ts +2 -1
  3. package/dist/components/calendar/calendar.js +126 -122
  4. package/dist/components/calendar/date-range-picker.cjs +1 -1
  5. package/dist/components/calendar/date-range-picker.d.ts +2 -1
  6. package/dist/components/calendar/date-range-picker.js +39 -39
  7. package/dist/components/charts/charts.cjs +1 -1
  8. package/dist/components/charts/charts.d.ts +13 -4
  9. package/dist/components/charts/charts.js +76 -46
  10. package/dist/components/charts/progress-ring.cjs +1 -1
  11. package/dist/components/charts/progress-ring.d.ts +3 -1
  12. package/dist/components/charts/progress-ring.js +11 -10
  13. package/dist/components/data-table/data-table-column-visibility-menu.cjs +1 -1
  14. package/dist/components/data-table/data-table-column-visibility-menu.d.ts +4 -1
  15. package/dist/components/data-table/data-table-column-visibility-menu.js +36 -8
  16. package/dist/components/data-table/data-table-pagination.cjs +1 -1
  17. package/dist/components/data-table/data-table-pagination.js +4 -4
  18. package/dist/components/data-table/data-table-toolbar.cjs +1 -1
  19. package/dist/components/data-table/data-table-toolbar.js +12 -13
  20. package/dist/components/data-table/data-table.cjs +1 -1
  21. package/dist/components/data-table/data-table.d.ts +2 -2
  22. package/dist/components/data-table/data-table.js +2 -1
  23. package/dist/components/display/carousel.cjs +1 -1
  24. package/dist/components/display/carousel.d.ts +15 -1
  25. package/dist/components/display/carousel.js +128 -86
  26. package/dist/components/display/code-block.cjs +2 -2
  27. package/dist/components/display/code-block.d.ts +2 -1
  28. package/dist/components/display/code-block.js +17 -12
  29. package/dist/components/display/delta-badge.cjs +1 -1
  30. package/dist/components/display/delta-badge.d.ts +2 -1
  31. package/dist/components/display/delta-badge.js +11 -7
  32. package/dist/components/display/kanban.cjs +1 -1
  33. package/dist/components/display/kanban.d.ts +4 -1
  34. package/dist/components/display/kanban.js +60 -33
  35. package/dist/components/display/metric-grid.cjs +1 -1
  36. package/dist/components/display/metric-grid.d.ts +1 -0
  37. package/dist/components/display/metric-grid.js +1 -1
  38. package/dist/components/display/qr-code.cjs +1 -1
  39. package/dist/components/display/qr-code.d.ts +2 -1
  40. package/dist/components/display/qr-code.js +19 -16
  41. package/dist/components/display/smart-card.d.ts +1 -1
  42. package/dist/components/display/status-legend.d.ts +1 -1
  43. package/dist/components/display/tag.cjs +1 -1
  44. package/dist/components/display/tag.d.ts +2 -1
  45. package/dist/components/display/tag.js +28 -22
  46. package/dist/components/display/tree-view.cjs +1 -1
  47. package/dist/components/display/tree-view.d.ts +9 -1
  48. package/dist/components/display/tree-view.js +104 -40
  49. package/dist/components/display/trend-card.cjs +1 -1
  50. package/dist/components/display/trend-card.js +27 -41
  51. package/dist/components/feedback/alert.cjs +1 -1
  52. package/dist/components/feedback/alert.d.ts +2 -1
  53. package/dist/components/feedback/alert.js +6 -6
  54. package/dist/components/feedback/loading-state.cjs +1 -1
  55. package/dist/components/feedback/loading-state.d.ts +3 -1
  56. package/dist/components/feedback/loading-state.js +23 -10
  57. package/dist/components/feedback/page-state.cjs +1 -1
  58. package/dist/components/feedback/page-state.d.ts +2 -1
  59. package/dist/components/feedback/page-state.js +7 -4
  60. package/dist/components/form/form-field-shell.cjs +1 -1
  61. package/dist/components/form/form-field-shell.d.ts +4 -2
  62. package/dist/components/form/form-field-shell.js +57 -41
  63. package/dist/components/form/form-input.cjs +1 -1
  64. package/dist/components/form/form-input.d.ts +3 -4
  65. package/dist/components/form/form-input.js +259 -257
  66. package/dist/components/form/form-select.cjs +1 -1
  67. package/dist/components/form/form-select.d.ts +2 -2
  68. package/dist/components/form/form-select.js +8 -6
  69. package/dist/components/form/form-switch.cjs +1 -1
  70. package/dist/components/form/form-switch.d.ts +1 -1
  71. package/dist/components/form/form-switch.js +58 -54
  72. package/dist/components/form/form-textarea.cjs +1 -1
  73. package/dist/components/form/form-textarea.d.ts +1 -1
  74. package/dist/components/form/form-textarea.js +29 -27
  75. package/dist/components/inputs/async-select.d.ts +3 -0
  76. package/dist/components/inputs/search-input.d.ts +3 -0
  77. package/dist/components/inputs/simple-select.cjs +1 -1
  78. package/dist/components/inputs/simple-select.d.ts +10 -32
  79. package/dist/components/inputs/simple-select.js +5 -101
  80. package/dist/components/layout/app-sidebar.cjs +1 -1
  81. package/dist/components/layout/app-sidebar.d.ts +1 -0
  82. package/dist/components/layout/app-sidebar.js +36 -36
  83. package/dist/components/layout/breadcrumbs.cjs +1 -1
  84. package/dist/components/layout/breadcrumbs.d.ts +2 -1
  85. package/dist/components/layout/breadcrumbs.js +7 -7
  86. package/dist/components/modern/calendar-scheduler.cjs +1 -1
  87. package/dist/components/modern/calendar-scheduler.d.ts +5 -1
  88. package/dist/components/modern/calendar-scheduler.js +47 -28
  89. package/dist/components/modern/dual-list-picker.cjs +1 -1
  90. package/dist/components/modern/dual-list-picker.d.ts +5 -1
  91. package/dist/components/modern/dual-list-picker.js +81 -23
  92. package/dist/components/modern/rich-text-editor.cjs +1 -1
  93. package/dist/components/modern/rich-text-editor.d.ts +3 -1
  94. package/dist/components/modern/rich-text-editor.js +12 -9
  95. package/dist/components/modern/tour.cjs +1 -1
  96. package/dist/components/modern/tour.d.ts +5 -1
  97. package/dist/components/modern/tour.js +57 -35
  98. package/dist/components/navigation/command-bar.cjs +1 -1
  99. package/dist/components/navigation/command-bar.d.ts +3 -1
  100. package/dist/components/navigation/command-bar.js +10 -7
  101. package/dist/components/navigation/demo.cjs +1 -1
  102. package/dist/components/navigation/demo.js +0 -1
  103. package/dist/components/navigation/nav-tabs.cjs +1 -1
  104. package/dist/components/navigation/nav-tabs.js +39 -27
  105. package/dist/components/navigation/page-tabs.cjs +1 -1
  106. package/dist/components/navigation/page-tabs.js +41 -30
  107. package/dist/components/navigation/pagination.cjs +1 -1
  108. package/dist/components/navigation/pagination.d.ts +7 -1
  109. package/dist/components/navigation/pagination.js +48 -25
  110. package/dist/components/notifications/notification-center.cjs +1 -1
  111. package/dist/components/notifications/notification-center.d.ts +3 -1
  112. package/dist/components/notifications/notification-center.js +56 -38
  113. package/dist/components/notifications/toast.cjs +1 -1
  114. package/dist/components/notifications/toast.d.ts +1 -0
  115. package/dist/components/notifications/toast.js +4 -0
  116. package/dist/components/overlay/alert-dialog.cjs +1 -1
  117. package/dist/components/overlay/alert-dialog.js +1 -1
  118. package/dist/components/overlay/confirm-dialog.cjs +1 -1
  119. package/dist/components/overlay/confirm-dialog.d.ts +4 -2
  120. package/dist/components/overlay/confirm-dialog.js +31 -22
  121. package/dist/components/overlay/drawer.cjs +1 -1
  122. package/dist/components/overlay/drawer.d.ts +3 -1
  123. package/dist/components/overlay/drawer.js +24 -16
  124. package/dist/components/ui/accordion/index.d.ts +4 -0
  125. package/dist/components/ui/badge/index.cjs +1 -1
  126. package/dist/components/ui/badge/index.d.ts +1 -1
  127. package/dist/components/ui/badge/index.js +2 -1
  128. package/dist/components/ui/button/index.cjs +1 -1
  129. package/dist/components/ui/button/index.d.ts +2 -1
  130. package/dist/components/ui/button/index.js +13 -10
  131. package/dist/components/ui/card/index.cjs +1 -1
  132. package/dist/components/ui/card/index.d.ts +13 -2
  133. package/dist/components/ui/card/index.js +74 -49
  134. package/dist/components/ui/dialog/index.cjs +1 -1
  135. package/dist/components/ui/dialog/index.js +2 -1
  136. package/dist/components/ui/hover-card.cjs +1 -1
  137. package/dist/components/ui/hover-card.d.ts +11 -3
  138. package/dist/components/ui/hover-card.js +29 -24
  139. package/dist/components/ui/input/index.cjs +1 -1
  140. package/dist/components/ui/input/index.d.ts +9 -1
  141. package/dist/components/ui/input/index.js +63 -30
  142. package/dist/components/ui/popover/index.cjs +1 -1
  143. package/dist/components/ui/popover/index.d.ts +2 -2
  144. package/dist/components/ui/popover/index.js +6 -5
  145. package/dist/components/ui/radio-group/index.cjs +1 -1
  146. package/dist/components/ui/radio-group/index.d.ts +5 -1
  147. package/dist/components/ui/radio-group/index.js +50 -16
  148. package/dist/components/ui/right-click-menu/index.cjs +1 -1
  149. package/dist/components/ui/right-click-menu/index.d.ts +5 -1
  150. package/dist/components/ui/right-click-menu/index.js +77 -23
  151. package/dist/components/ui/segmented-control/index.cjs +1 -1
  152. package/dist/components/ui/segmented-control/index.d.ts +2 -1
  153. package/dist/components/ui/segmented-control/index.js +23 -11
  154. package/dist/components/ui/select/index.cjs +1 -1
  155. package/dist/components/ui/select/index.d.ts +40 -1
  156. package/dist/components/ui/select/index.js +159 -48
  157. package/dist/components/ui/switch/index.cjs +1 -1
  158. package/dist/components/ui/switch/index.d.ts +18 -0
  159. package/dist/components/ui/switch/index.js +47 -17
  160. package/dist/components/ui/tabs/index.cjs +1 -1
  161. package/dist/components/ui/tabs/index.d.ts +14 -4
  162. package/dist/components/ui/tabs/index.js +11 -8
  163. package/dist/components/ui/textarea/index.cjs +1 -1
  164. package/dist/components/ui/textarea/index.d.ts +10 -2
  165. package/dist/components/ui/textarea/index.js +37 -8
  166. package/dist/components/ui/textarea.cjs +1 -0
  167. package/dist/components/ui/textarea.d.ts +1 -0
  168. package/dist/components/ui/textarea.js +2 -0
  169. package/dist/components/ui/tooltip/index.cjs +1 -1
  170. package/dist/components/ui/tooltip/index.d.ts +11 -3
  171. package/dist/components/ui/tooltip/index.js +41 -20
  172. package/dist/components/upload/file-upload.cjs +1 -1
  173. package/dist/components/upload/file-upload.d.ts +8 -1
  174. package/dist/components/upload/file-upload.js +132 -100
  175. package/dist/components/upload/image-upload.cjs +1 -1
  176. package/dist/components/upload/image-upload.d.ts +5 -1
  177. package/dist/components/upload/image-upload.js +34 -9
  178. package/dist/index.cjs +1 -1
  179. package/dist/index.js +31 -31
  180. package/dist/public-component-surface.cjs +1 -1
  181. package/dist/public-component-surface.js +15 -0
  182. package/dist/showcase/component-api-schema.cjs +1 -1
  183. package/dist/showcase/component-api-schema.js +187 -10
  184. package/dist/showcase/create-demo.cjs +5 -4
  185. package/dist/showcase/create-demo.js +2 -2
  186. package/dist/showcase/fallback.cjs +3 -3
  187. package/dist/showcase/fallback.js +221 -243
  188. package/dist/showcase/premium/alert/showcase.cjs +1 -1
  189. package/dist/showcase/premium/alert/showcase.js +1 -0
  190. package/dist/showcase/premium/app-sidebar/showcase.cjs +1 -1
  191. package/dist/showcase/premium/app-sidebar/showcase.js +1 -0
  192. package/dist/showcase/premium/badge/showcase.cjs +1 -1
  193. package/dist/showcase/premium/badge/showcase.js +7 -0
  194. package/dist/showcase/premium/badge/types.d.ts +1 -1
  195. package/dist/showcase/premium/breadcrumbs/showcase.cjs +1 -1
  196. package/dist/showcase/premium/breadcrumbs/showcase.js +12 -1
  197. package/dist/showcase/premium/button/mock.cjs +1 -4
  198. package/dist/showcase/premium/button/mock.js +1 -1
  199. package/dist/showcase/premium/button/showcase.cjs +1 -1
  200. package/dist/showcase/premium/button/showcase.js +2 -2
  201. package/dist/showcase/premium/card/showcase.cjs +1 -1
  202. package/dist/showcase/premium/card/showcase.js +96 -47
  203. package/dist/showcase/premium/carousel/showcase.cjs +1 -1
  204. package/dist/showcase/premium/carousel/showcase.js +76 -49
  205. package/dist/showcase/premium/command-bar/showcase.cjs +1 -1
  206. package/dist/showcase/premium/command-bar/showcase.js +2 -0
  207. package/dist/showcase/premium/data-table/mock.cjs +12 -11
  208. package/dist/showcase/premium/data-table/mock.js +1 -1
  209. package/dist/showcase/premium/data-table/showcase.cjs +1 -1
  210. package/dist/showcase/premium/data-table/showcase.js +1 -1
  211. package/dist/showcase/premium/data-table-parts/showcase.cjs +1 -1
  212. package/dist/showcase/premium/data-table-parts/showcase.js +3 -1
  213. package/dist/showcase/premium/file-upload/showcase.cjs +1 -1
  214. package/dist/showcase/premium/file-upload/showcase.js +25 -4
  215. package/dist/showcase/premium/image-upload/showcase.cjs +1 -1
  216. package/dist/showcase/premium/image-upload/showcase.js +4 -1
  217. package/dist/showcase/premium/index.cjs +1 -1
  218. package/dist/showcase/premium/index.js +396 -402
  219. package/dist/showcase/premium/loading-state/showcase.cjs +1 -1
  220. package/dist/showcase/premium/loading-state/showcase.js +3 -1
  221. package/dist/showcase/premium/metric-grid/showcase.cjs +1 -1
  222. package/dist/showcase/premium/metric-grid/showcase.js +96 -28
  223. package/dist/showcase/premium/notification-center/showcase.cjs +1 -1
  224. package/dist/showcase/premium/notification-center/showcase.js +7 -3
  225. package/dist/showcase/premium/page-state/showcase.cjs +1 -1
  226. package/dist/showcase/premium/page-state/showcase.js +5 -1
  227. package/dist/showcase/premium/pagination/showcase.cjs +1 -1
  228. package/dist/showcase/premium/pagination/showcase.js +15 -2
  229. package/dist/showcase/premium/popover/showcase.cjs +1 -1
  230. package/dist/showcase/premium/popover/showcase.js +85 -50
  231. package/dist/showcase/premium/radio-group/showcase.cjs +1 -1
  232. package/dist/showcase/premium/radio-group/showcase.js +27 -4
  233. package/dist/showcase/premium/right-click-menu/showcase.cjs +1 -1
  234. package/dist/showcase/premium/right-click-menu/showcase.js +56 -43
  235. package/dist/showcase/premium/segmented-control/showcase.cjs +1 -1
  236. package/dist/showcase/premium/segmented-control/showcase.js +1 -0
  237. package/dist/showcase/premium/select/data.cjs +1 -1
  238. package/dist/showcase/premium/select/data.js +69 -34
  239. package/dist/showcase/premium/select/mock.cjs +20 -8
  240. package/dist/showcase/premium/select/mock.js +3 -2
  241. package/dist/showcase/premium/select/showcase.cjs +1 -1
  242. package/dist/showcase/premium/select/showcase.js +101 -86
  243. package/dist/showcase/premium/select/types.d.ts +3 -0
  244. package/dist/showcase/premium/statistic/showcase.cjs +1 -1
  245. package/dist/showcase/premium/statistic/showcase.js +57 -25
  246. package/dist/showcase/premium/switch/showcase.cjs +1 -1
  247. package/dist/showcase/premium/switch/showcase.js +25 -14
  248. package/dist/showcase/premium/tabs/showcase.cjs +1 -1
  249. package/dist/showcase/premium/tabs/showcase.js +171 -48
  250. package/dist/showcase/premium/textarea/mock.cjs +12 -4
  251. package/dist/showcase/premium/textarea/mock.js +1 -1
  252. package/dist/showcase/premium/textarea/showcase.cjs +1 -1
  253. package/dist/showcase/premium/textarea/showcase.js +8 -3
  254. package/dist/showcase/premium/toast/showcase.cjs +1 -1
  255. package/dist/showcase/premium/toast/showcase.js +32 -6
  256. package/dist/showcase/premium/types.d.ts +1 -1
  257. package/dist/showcase/registry-quality.cjs +1 -1
  258. package/dist/showcase/registry-quality.js +1 -0
  259. package/dist/showcase/registry-specific.cjs +1 -1
  260. package/dist/showcase/registry-specific.js +78 -74
  261. package/dist/showcase/render-registry-preview.cjs +1 -1
  262. package/dist/showcase/render-registry-preview.js +90 -108
  263. package/dist/showcase/site-data.cjs +1 -1
  264. package/dist/showcase/site-data.js +60 -21
  265. package/dist/showcase/tembro-registry.json.cjs +1 -1
  266. package/dist/showcase/tembro-registry.json.js +34 -20
  267. package/dist/showcase/types.d.ts +1 -1
  268. package/package.json +1 -1
  269. package/packages/cli/dist/index.cjs +31 -31
  270. package/packages/cli/vendor/src/components/calendar/calendar.tsx +59 -50
  271. package/packages/cli/vendor/src/components/calendar/date-range-picker.tsx +7 -4
  272. package/packages/cli/vendor/src/components/charts/charts.tsx +109 -66
  273. package/packages/cli/vendor/src/components/charts/progress-ring.tsx +37 -26
  274. package/packages/cli/vendor/src/components/data-table/data-table-column-visibility-menu.tsx +41 -22
  275. package/packages/cli/vendor/src/components/data-table/data-table-pagination.tsx +7 -7
  276. package/packages/cli/vendor/src/components/data-table/data-table-toolbar.tsx +8 -6
  277. package/packages/cli/vendor/src/components/data-table/data-table.tsx +21 -20
  278. package/packages/cli/vendor/src/components/display/carousel.tsx +102 -9
  279. package/packages/cli/vendor/src/components/display/code-block.tsx +22 -2
  280. package/packages/cli/vendor/src/components/display/delta-badge.tsx +11 -11
  281. package/packages/cli/vendor/src/components/display/kanban.tsx +103 -57
  282. package/packages/cli/vendor/src/components/display/metric-grid.tsx +16 -13
  283. package/packages/cli/vendor/src/components/display/qr-code.tsx +17 -15
  284. package/packages/cli/vendor/src/components/display/smart-card.tsx +1 -1
  285. package/packages/cli/vendor/src/components/display/status-legend.tsx +1 -1
  286. package/packages/cli/vendor/src/components/display/tag.tsx +39 -21
  287. package/packages/cli/vendor/src/components/display/tree-view.tsx +221 -84
  288. package/packages/cli/vendor/src/components/display/trend-card.tsx +6 -40
  289. package/packages/cli/vendor/src/components/feedback/alert.tsx +3 -1
  290. package/packages/cli/vendor/src/components/feedback/loading-state.tsx +33 -17
  291. package/packages/cli/vendor/src/components/feedback/page-state.tsx +8 -7
  292. package/packages/cli/vendor/src/components/form/form-field-shell.tsx +37 -8
  293. package/packages/cli/vendor/src/components/form/form-input.tsx +11 -12
  294. package/packages/cli/vendor/src/components/form/form-select.tsx +6 -4
  295. package/packages/cli/vendor/src/components/form/form-switch.tsx +9 -3
  296. package/packages/cli/vendor/src/components/form/form-textarea.tsx +6 -2
  297. package/packages/cli/vendor/src/components/inputs/async-select.tsx +11 -8
  298. package/packages/cli/vendor/src/components/inputs/search-input.tsx +5 -2
  299. package/packages/cli/vendor/src/components/inputs/simple-select.tsx +20 -190
  300. package/packages/cli/vendor/src/components/layout/app-sidebar.tsx +3 -1
  301. package/packages/cli/vendor/src/components/layout/breadcrumbs.tsx +3 -1
  302. package/packages/cli/vendor/src/components/modern/calendar-scheduler.tsx +28 -13
  303. package/packages/cli/vendor/src/components/modern/dual-list-picker.tsx +103 -35
  304. package/packages/cli/vendor/src/components/modern/rich-text-editor.tsx +25 -22
  305. package/packages/cli/vendor/src/components/modern/tour.tsx +47 -29
  306. package/packages/cli/vendor/src/components/navigation/command-bar.tsx +6 -0
  307. package/packages/cli/vendor/src/components/navigation/demo.tsx +0 -1
  308. package/packages/cli/vendor/src/components/navigation/nav-tabs.tsx +38 -29
  309. package/packages/cli/vendor/src/components/navigation/page-tabs.tsx +35 -23
  310. package/packages/cli/vendor/src/components/navigation/pagination.tsx +65 -31
  311. package/packages/cli/vendor/src/components/notifications/notification-center.tsx +64 -39
  312. package/packages/cli/vendor/src/components/notifications/toast.tsx +23 -21
  313. package/packages/cli/vendor/src/components/overlay/alert-dialog.tsx +1 -1
  314. package/packages/cli/vendor/src/components/overlay/confirm-dialog.tsx +45 -22
  315. package/packages/cli/vendor/src/components/overlay/drawer.tsx +18 -5
  316. package/packages/cli/vendor/src/components/ui/accordion/index.tsx +4 -0
  317. package/packages/cli/vendor/src/components/ui/badge/index.tsx +2 -1
  318. package/packages/cli/vendor/src/components/ui/button/index.tsx +11 -5
  319. package/packages/cli/vendor/src/components/ui/card/index.tsx +95 -25
  320. package/packages/cli/vendor/src/components/ui/dialog/index.tsx +2 -1
  321. package/packages/cli/vendor/src/components/ui/hover-card.tsx +54 -28
  322. package/packages/cli/vendor/src/components/ui/input/index.tsx +98 -0
  323. package/packages/cli/vendor/src/components/ui/popover/index.tsx +10 -8
  324. package/packages/cli/vendor/src/components/ui/radio-group/index.tsx +55 -6
  325. package/packages/cli/vendor/src/components/ui/right-click-menu/index.tsx +120 -9
  326. package/packages/cli/vendor/src/components/ui/segmented-control/index.tsx +29 -3
  327. package/packages/cli/vendor/src/components/ui/select/index.tsx +260 -34
  328. package/packages/cli/vendor/src/components/ui/switch/index.tsx +71 -6
  329. package/packages/cli/vendor/src/components/ui/tabs/index.tsx +22 -6
  330. package/packages/cli/vendor/src/components/ui/textarea/index.tsx +105 -15
  331. package/packages/cli/vendor/src/components/ui/textarea.tsx +2 -0
  332. package/packages/cli/vendor/src/components/ui/tooltip/index.tsx +67 -22
  333. package/packages/cli/vendor/src/components/upload/file-upload.tsx +120 -57
  334. package/packages/cli/vendor/src/components/upload/image-upload.tsx +71 -24
  335. package/packages/cli/vendor/src/public-component-surface.ts +3 -0
  336. package/packages/cli/vendor/src/showcase/component-api-schema.ts +79 -41
  337. package/packages/cli/vendor/src/showcase/create-demo.tsx +16 -15
  338. package/packages/cli/vendor/src/showcase/fallback.tsx +4 -19
  339. package/packages/cli/vendor/src/showcase/premium/alert/showcase.tsx +1 -0
  340. package/packages/cli/vendor/src/showcase/premium/app-sidebar/showcase.tsx +1 -0
  341. package/packages/cli/vendor/src/showcase/premium/badge/showcase.tsx +4 -2
  342. package/packages/cli/vendor/src/showcase/premium/badge/types.ts +1 -1
  343. package/packages/cli/vendor/src/showcase/premium/breadcrumbs/showcase.tsx +3 -1
  344. package/packages/cli/vendor/src/showcase/premium/button/mock.ts +2 -5
  345. package/packages/cli/vendor/src/showcase/premium/button/showcase.tsx +2 -2
  346. package/packages/cli/vendor/src/showcase/premium/card/showcase.tsx +26 -1
  347. package/packages/cli/vendor/src/showcase/premium/carousel/showcase.tsx +19 -3
  348. package/packages/cli/vendor/src/showcase/premium/command-bar/showcase.tsx +1 -1
  349. package/packages/cli/vendor/src/showcase/premium/data-table/mock.ts +26 -25
  350. package/packages/cli/vendor/src/showcase/premium/data-table/showcase.tsx +3 -3
  351. package/packages/cli/vendor/src/showcase/premium/data-table-parts/showcase.tsx +3 -3
  352. package/packages/cli/vendor/src/showcase/premium/file-upload/showcase.tsx +21 -1
  353. package/packages/cli/vendor/src/showcase/premium/image-upload/showcase.tsx +4 -1
  354. package/packages/cli/vendor/src/showcase/premium/index.ts +0 -2
  355. package/packages/cli/vendor/src/showcase/premium/loading-state/showcase.tsx +1 -1
  356. package/packages/cli/vendor/src/showcase/premium/metric-grid/showcase.tsx +36 -4
  357. package/packages/cli/vendor/src/showcase/premium/notification-center/showcase.tsx +4 -3
  358. package/packages/cli/vendor/src/showcase/premium/page-state/showcase.tsx +1 -0
  359. package/packages/cli/vendor/src/showcase/premium/pagination/showcase.tsx +13 -1
  360. package/packages/cli/vendor/src/showcase/premium/popover/showcase.tsx +27 -11
  361. package/packages/cli/vendor/src/showcase/premium/radio-group/showcase.tsx +13 -1
  362. package/packages/cli/vendor/src/showcase/premium/right-click-menu/showcase.tsx +8 -5
  363. package/packages/cli/vendor/src/showcase/premium/segmented-control/showcase.tsx +1 -0
  364. package/packages/cli/vendor/src/showcase/premium/select/data.ts +12 -3
  365. package/packages/cli/vendor/src/showcase/premium/select/mock.ts +4 -4
  366. package/packages/cli/vendor/src/showcase/premium/select/showcase.tsx +35 -22
  367. package/packages/cli/vendor/src/showcase/premium/select/types.ts +3 -0
  368. package/packages/cli/vendor/src/showcase/premium/statistic/showcase.tsx +10 -1
  369. package/packages/cli/vendor/src/showcase/premium/switch/showcase.tsx +15 -6
  370. package/packages/cli/vendor/src/showcase/premium/tabs/showcase.tsx +48 -1
  371. package/packages/cli/vendor/src/showcase/premium/textarea/mock.ts +12 -4
  372. package/packages/cli/vendor/src/showcase/premium/textarea/showcase.tsx +5 -0
  373. package/packages/cli/vendor/src/showcase/premium/toast/showcase.tsx +17 -1
  374. package/packages/cli/vendor/src/showcase/premium/types.ts +1 -1
  375. package/packages/cli/vendor/src/showcase/registry-quality.ts +3 -2
  376. package/packages/cli/vendor/src/showcase/registry-specific.tsx +7 -8
  377. package/packages/cli/vendor/src/showcase/render-registry-preview.tsx +5 -21
  378. package/packages/cli/vendor/src/showcase/site-data.tsx +21 -15
  379. package/packages/cli/vendor/src/showcase/tembro-registry.json +42 -20
  380. package/packages/cli/vendor/src/showcase/types.ts +1 -1
  381. package/registry.json +18 -6
@@ -65,14 +65,28 @@ type CardSurfaceSlots = {
65
65
  media?: React.ReactNode
66
66
  content?: React.ReactNode
67
67
  footer?: React.ReactNode
68
+ mediaClassName?: string
69
+ bodyClassName?: string
68
70
  headerClassName?: string
71
+ eyebrowClassName?: string
69
72
  titleClassName?: string
70
73
  descriptionClassName?: string
71
74
  contentClassName?: string
72
75
  footerClassName?: string
73
76
  }
74
77
 
75
- export type CardProps = Omit<React.ComponentProps<"div">, keyof CardSurfaceSlots> & VariantProps<typeof cardVariants> & CardSurfaceSlots
78
+ export type CardOrientation = "vertical" | "horizontal"
79
+ export type CardMediaAspect = "auto" | "square" | "video" | "poster" | "wide"
80
+ export type CardPadding = "none" | "sm" | "default" | "lg"
81
+
82
+ export type CardProps = Omit<React.ComponentProps<"div">, keyof CardSurfaceSlots> &
83
+ VariantProps<typeof cardVariants> &
84
+ CardSurfaceSlots & {
85
+ orientation?: CardOrientation
86
+ mediaPosition?: "start" | "end"
87
+ mediaAspect?: CardMediaAspect
88
+ padding?: CardPadding
89
+ }
76
90
 
77
91
  function hasSurfaceContent(props: CardSurfaceSlots) {
78
92
  return (
@@ -96,6 +110,10 @@ function Card({
96
110
  interactive,
97
111
  selected,
98
112
  disabled,
113
+ orientation = "vertical",
114
+ mediaPosition = "start",
115
+ mediaAspect = "auto",
116
+ padding = "default",
99
117
  tabIndex,
100
118
  eyebrow,
101
119
  title,
@@ -105,7 +123,10 @@ function Card({
105
123
  media,
106
124
  content,
107
125
  footer,
126
+ mediaClassName,
127
+ bodyClassName,
108
128
  headerClassName,
129
+ eyebrowClassName,
109
130
  titleClassName,
110
131
  descriptionClassName,
111
132
  contentClassName,
@@ -126,6 +147,36 @@ function Card({
126
147
  const resolvedContent = content ?? children
127
148
  const hasHeader = eyebrow != null || title != null || description != null || badge != null || action != null
128
149
  const hasFooter = footer != null
150
+ const mediaNode = media ? (
151
+ <div
152
+ data-slot="card-media"
153
+ data-media-position={mediaPosition}
154
+ data-media-aspect={mediaAspect}
155
+ className={cn(
156
+ "overflow-hidden",
157
+ orientation === "horizontal" ? "shrink-0 self-stretch" : "",
158
+ mediaAspect === "square" && (orientation === "horizontal" ? "w-40" : "aspect-square"),
159
+ mediaAspect === "video" && (orientation === "horizontal" ? "w-56" : "aspect-video"),
160
+ mediaAspect === "poster" && (orientation === "horizontal" ? "w-36" : "aspect-[3/4]"),
161
+ mediaAspect === "wide" && (orientation === "horizontal" ? "w-72" : "aspect-[16/7]"),
162
+ mediaClassName
163
+ )}
164
+ >
165
+ {media}
166
+ </div>
167
+ ) : null
168
+ const surfacePaddingClassName = {
169
+ none: "",
170
+ sm: "px-4",
171
+ default: "px-(--card-spacing)",
172
+ lg: "px-6",
173
+ } satisfies Record<CardPadding, string>
174
+ const bodyPaddingClassName = {
175
+ none: "",
176
+ sm: "pb-4",
177
+ default: "",
178
+ lg: "pb-6",
179
+ } satisfies Record<CardPadding, string>
129
180
 
130
181
  return (
131
182
  <div
@@ -139,37 +190,56 @@ function Card({
139
190
  data-selected={selected || undefined}
140
191
  data-disabled={disabled || undefined}
141
192
  data-has-footer={hasFooter || undefined}
193
+ data-orientation={orientation}
194
+ data-padding={padding}
142
195
  aria-disabled={disabled || undefined}
143
196
  tabIndex={interactive && !disabled ? tabIndex ?? 0 : tabIndex}
144
- className={cn(cardVariants({ variant, size, density, tone, interactive, selected, disabled }), className)}
197
+ className={cn(
198
+ cardVariants({ variant, size, density, tone, interactive, selected, disabled }),
199
+ orientation === "horizontal" && "flex-row py-0",
200
+ interactive && "hover:border-[color:var(--aui-control-hover-border,var(--ring))] hover:shadow-[var(--aui-card-shadow-hover,var(--aui-card-shadow,0_12px_32px_rgba(15,23,42,0.08)))]",
201
+ selected && "border-[color:var(--aui-control-border-strong,var(--ring))] shadow-[var(--aui-card-shadow-hover,var(--aui-card-shadow,0_12px_32px_rgba(15,23,42,0.08)))]",
202
+ className
203
+ )}
145
204
  {...props}
146
205
  >
147
206
  {surfaceMode ? (
148
207
  <>
149
- {media}
150
- {hasHeader ? (
151
- <CardHeader className={headerClassName}>
152
- <div className="min-w-0 space-y-1">
153
- {eyebrow != null ? (
154
- <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground/80">
155
- {eyebrow}
156
- </div>
157
- ) : null}
158
- {title != null ? <CardTitle className={titleClassName}>{title}</CardTitle> : null}
159
- {description != null ? (
160
- <CardDescription className={descriptionClassName}>{description}</CardDescription>
208
+ {mediaPosition === "start" ? mediaNode : null}
209
+ <div
210
+ data-slot="card-body"
211
+ className={cn(
212
+ "flex min-w-0 flex-1 flex-col",
213
+ orientation === "horizontal" ? "py-(--card-spacing)" : "",
214
+ bodyPaddingClassName[padding],
215
+ bodyClassName
216
+ )}
217
+ >
218
+ {hasHeader ? (
219
+ <CardHeader className={cn(surfacePaddingClassName[padding], headerClassName)}>
220
+ <div className="min-w-0 space-y-1">
221
+ {eyebrow != null ? (
222
+ <div className={cn("text-[11px] font-semibold uppercase tracking-[0.18em] text-muted-foreground/80", eyebrowClassName)}>
223
+ {eyebrow}
224
+ </div>
225
+ ) : null}
226
+ {title != null ? <CardTitle className={titleClassName}>{title}</CardTitle> : null}
227
+ {description != null ? (
228
+ <CardDescription className={descriptionClassName}>{description}</CardDescription>
229
+ ) : null}
230
+ </div>
231
+ {badge != null || action != null ? (
232
+ <CardAction className="flex items-center gap-2">
233
+ {badge}
234
+ {action}
235
+ </CardAction>
161
236
  ) : null}
162
- </div>
163
- {badge != null || action != null ? (
164
- <CardAction className="flex items-center gap-2">
165
- {badge}
166
- {action}
167
- </CardAction>
168
- ) : null}
169
- </CardHeader>
170
- ) : null}
171
- {resolvedContent != null ? <CardContent className={contentClassName}>{resolvedContent}</CardContent> : null}
172
- {hasFooter ? <CardFooter className={footerClassName}>{footer}</CardFooter> : null}
237
+ </CardHeader>
238
+ ) : null}
239
+ {resolvedContent != null ? <CardContent className={cn(surfacePaddingClassName[padding], contentClassName)}>{resolvedContent}</CardContent> : null}
240
+ {hasFooter ? <CardFooter className={cn(surfacePaddingClassName[padding], footerClassName)}>{footer}</CardFooter> : null}
241
+ </div>
242
+ {mediaPosition === "end" ? mediaNode : null}
173
243
  </>
174
244
  ) : (
175
245
  children
@@ -70,8 +70,9 @@ function DialogContent({
70
70
  data-size={size}
71
71
  data-surface={surface}
72
72
  role="dialog"
73
+ aria-modal="true"
73
74
  className={cn(
74
- "fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-5 overflow-hidden rounded-[var(--radius-3xl)] border border-[color:var(--aui-card-border,var(--border))] bg-[color:var(--aui-overlay-surface,var(--popover))] p-6 text-sm text-popover-foreground shadow-[var(--aui-control-panel-shadow,0_24px_70px_rgba(15,23,42,0.22))] backdrop-blur duration-100 outline-none data-[surface=plain]:overflow-visible data-[surface=plain]:border-transparent data-[surface=plain]:bg-transparent data-[surface=plain]:p-0 data-[surface=plain]:shadow-none data-[size=xs]:sm:max-w-sm data-[size=sm]:sm:max-w-md data-[size=md]:sm:max-w-lg data-[size=lg]:sm:max-w-2xl data-[size=xl]:sm:max-w-4xl data-[size=full]:h-[min(92vh,56rem)] data-[size=full]:max-w-[min(96vw,84rem)] data-[size=full]:grid-rows-[auto_minmax(0,1fr)] data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
75
+ "fixed top-1/2 left-1/2 z-50 grid max-h-[min(92vh,calc(100dvh-2rem))] w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-5 overflow-y-auto overscroll-contain rounded-[var(--radius-3xl)] border border-[color:var(--aui-card-border,var(--border))] bg-[color:var(--aui-overlay-surface,var(--popover))] p-6 text-sm text-popover-foreground shadow-[var(--aui-control-panel-shadow,0_24px_70px_rgba(15,23,42,0.22))] backdrop-blur duration-100 outline-none data-[surface=plain]:overflow-visible data-[surface=plain]:border-transparent data-[surface=plain]:bg-transparent data-[surface=plain]:p-0 data-[surface=plain]:shadow-none data-[size=xs]:sm:max-w-sm data-[size=sm]:sm:max-w-md data-[size=md]:sm:max-w-lg data-[size=lg]:sm:max-w-2xl data-[size=xl]:sm:max-w-4xl data-[size=full]:h-[min(92vh,56rem)] data-[size=full]:max-w-[min(96vw,84rem)] data-[size=full]:grid-rows-[auto_minmax(0,1fr)] data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
75
76
  className
76
77
  )}
77
78
  {...props}
@@ -1,51 +1,77 @@
1
1
  import * as React from "react"
2
+ import { PreviewCard as PreviewCardPrimitive } from "@base-ui/react/preview-card"
2
3
 
3
4
  import { cn } from "@/lib/utils"
4
5
 
5
- export type HoverCardProps = Omit<React.ComponentProps<"div">, "content"> & {
6
+ export type HoverCardProps = Omit<PreviewCardPrimitive.Root.Props, "children"> &
7
+ Omit<React.ComponentProps<"span">, "content" | "children"> & {
6
8
  trigger: React.ReactNode
7
9
  content: React.ReactNode
8
- side?: "top" | "right" | "bottom" | "left"
10
+ side?: PreviewCardPrimitive.Positioner.Props["side"]
11
+ align?: PreviewCardPrimitive.Positioner.Props["align"]
12
+ sideOffset?: PreviewCardPrimitive.Positioner.Props["sideOffset"]
13
+ alignOffset?: PreviewCardPrimitive.Positioner.Props["alignOffset"]
14
+ collisionPadding?: PreviewCardPrimitive.Positioner.Props["collisionPadding"]
15
+ delay?: PreviewCardPrimitive.Trigger.Props["delay"]
16
+ closeDelay?: PreviewCardPrimitive.Trigger.Props["closeDelay"]
17
+ disabled?: boolean
9
18
  contentClassName?: string
10
19
  }
11
20
 
12
- const sideClassName = {
13
- top: "bottom-full left-1/2 mb-2.5 -translate-x-1/2",
14
- right: "left-full top-1/2 ml-2.5 -translate-y-1/2",
15
- bottom: "left-1/2 top-full mt-2.5 -translate-x-1/2",
16
- left: "right-full top-1/2 mr-2.5 -translate-y-1/2",
17
- } as const
18
-
19
21
  function HoverCard({
20
22
  trigger,
21
23
  content,
22
24
  side = "bottom",
25
+ align = "center",
26
+ sideOffset = 10,
27
+ alignOffset = 0,
28
+ collisionPadding = 12,
29
+ delay = 450,
30
+ closeDelay = 180,
31
+ disabled = false,
23
32
  contentClassName,
24
33
  className,
25
- children,
26
34
  ...props
27
35
  }: HoverCardProps) {
28
- return (
29
- <div
30
- data-slot="hover-card"
31
- className={cn("group/hover-card relative inline-flex", className)}
32
- {...props}
33
- >
34
- <span data-slot="hover-card-trigger" className="inline-flex">
36
+ if (disabled) {
37
+ return (
38
+ <span data-slot="hover-card" className={cn("inline-flex", className)} {...props}>
35
39
  {trigger}
36
40
  </span>
37
- <div
38
- data-slot="hover-card-content"
39
- className={cn(
40
- "pointer-events-none absolute z-50 min-w-60 rounded-[var(--radius-2xl)] border border-border/80 bg-popover/98 p-4 text-sm text-popover-foreground opacity-0 shadow-[0_18px_42px_color-mix(in_oklch,var(--foreground),transparent_86%)] ring-1 ring-foreground/8 backdrop-blur transition duration-150 group-hover/hover-card:pointer-events-auto group-hover/hover-card:opacity-100 group-focus-within/hover-card:pointer-events-auto group-focus-within/hover-card:opacity-100",
41
- sideClassName[side],
42
- contentClassName
43
- )}
41
+ )
42
+ }
43
+
44
+ return (
45
+ <PreviewCardPrimitive.Root>
46
+ <PreviewCardPrimitive.Trigger
47
+ data-slot="hover-card-trigger"
48
+ delay={delay}
49
+ closeDelay={closeDelay}
50
+ render={<span data-slot="hover-card" className={cn("inline-flex", className)} {...props} />}
44
51
  >
45
- {content}
46
- </div>
47
- {children}
48
- </div>
52
+ {trigger}
53
+ </PreviewCardPrimitive.Trigger>
54
+ <PreviewCardPrimitive.Portal>
55
+ <PreviewCardPrimitive.Positioner
56
+ className="isolate z-50"
57
+ side={side}
58
+ align={align}
59
+ sideOffset={sideOffset}
60
+ alignOffset={alignOffset}
61
+ collisionPadding={collisionPadding}
62
+ >
63
+ <PreviewCardPrimitive.Popup
64
+ data-slot="hover-card-content"
65
+ className={cn(
66
+ "z-50 min-w-60 max-w-[min(24rem,calc(100vw-1rem))] origin-(--transform-origin) rounded-[var(--aui-card-radius,var(--radius-xl))] border border-border/80 bg-popover/98 p-4 text-sm text-popover-foreground shadow-[0_18px_42px_color-mix(in_oklch,var(--foreground),transparent_86%)] ring-1 ring-foreground/8 outline-hidden backdrop-blur duration-150 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
67
+ contentClassName
68
+ )}
69
+ >
70
+ {content}
71
+ </PreviewCardPrimitive.Popup>
72
+ </PreviewCardPrimitive.Positioner>
73
+ </PreviewCardPrimitive.Portal>
74
+ </PreviewCardPrimitive.Root>
49
75
  )
50
76
  }
51
77
 
@@ -39,6 +39,7 @@ export type InputTextProps = Omit<InputPrimitiveProps, "value"> & {
39
39
  kind?: "text"
40
40
  value?: string | number | readonly string[] | null
41
41
  onValueChange?: (value: string) => void
42
+ onDebouncedValueChange?: (value: string) => void
42
43
  leading?: React.ReactNode
43
44
  trailing?: React.ReactNode
44
45
  trailingAction?: React.ReactNode
@@ -57,6 +58,13 @@ export type InputTextProps = Omit<InputPrimitiveProps, "value"> & {
57
58
  helperClassName?: string
58
59
  leadingPointerEvents?: boolean
59
60
  trailingPointerEvents?: boolean
61
+ searchIcon?: React.ReactNode
62
+ loading?: boolean
63
+ loadingLabel?: string
64
+ resultCount?: number
65
+ shortcut?: React.ReactNode
66
+ debounceMs?: number
67
+ showMetaOnClear?: boolean
60
68
  }
61
69
 
62
70
  export type InputClearableProps = Omit<ClearableInputProps, "kind"> & {
@@ -121,6 +129,20 @@ function getInputTextLength(value: InputTextProps["value"] | InputTextProps["def
121
129
  return 0
122
130
  }
123
131
 
132
+ function shouldRenderSearchInput(props: InputTextProps) {
133
+ return (
134
+ props.type === "search" ||
135
+ props.searchIcon !== undefined ||
136
+ props.loading !== undefined ||
137
+ props.loadingLabel !== undefined ||
138
+ props.resultCount !== undefined ||
139
+ props.shortcut !== undefined ||
140
+ props.debounceMs !== undefined ||
141
+ props.showMetaOnClear !== undefined ||
142
+ props.onDebouncedValueChange !== undefined
143
+ )
144
+ }
145
+
124
146
  const Input = React.forwardRef<HTMLInputElement | HTMLDivElement, InputProps>((props, ref) => {
125
147
  const kind = props.kind ?? "text"
126
148
 
@@ -210,6 +232,82 @@ const Input = React.forwardRef<HTMLInputElement | HTMLDivElement, InputProps>((p
210
232
  }
211
233
 
212
234
  const inputProps = props as Omit<InputTextProps, "kind">
235
+
236
+ if (shouldRenderSearchInput(inputProps)) {
237
+ const {
238
+ leading,
239
+ searchIcon,
240
+ helperText,
241
+ errorText,
242
+ showCharacterCount,
243
+ countFormatter,
244
+ helperClassName,
245
+ inputClassName,
246
+ ...searchInputProps
247
+ } = inputProps
248
+ const searchValue: SearchInputProps["value"] = Array.isArray(inputProps.value)
249
+ ? inputProps.value.join(" ")
250
+ : inputProps.value == null || typeof inputProps.value === "string" || typeof inputProps.value === "number"
251
+ ? inputProps.value
252
+ : String(inputProps.value)
253
+ const searchDefaultValue: SearchInputProps["defaultValue"] = Array.isArray(inputProps.defaultValue)
254
+ ? inputProps.defaultValue.join(" ")
255
+ : inputProps.defaultValue == null ||
256
+ typeof inputProps.defaultValue === "string" ||
257
+ typeof inputProps.defaultValue === "number"
258
+ ? inputProps.defaultValue
259
+ : String(inputProps.defaultValue)
260
+
261
+ const searchInput = (
262
+ <SearchInput
263
+ ref={ref as React.ForwardedRef<HTMLInputElement>}
264
+ searchIcon={searchIcon ?? leading}
265
+ inputClassName={inputClassName}
266
+ {...searchInputProps}
267
+ value={searchValue}
268
+ defaultValue={searchDefaultValue}
269
+ />
270
+ )
271
+
272
+ if (!helperText && !errorText && !showCharacterCount) {
273
+ return searchInput
274
+ }
275
+
276
+ const currentLength = getInputTextLength(inputProps.value ?? inputProps.defaultValue)
277
+
278
+ return (
279
+ <div data-slot="input-field" className="grid gap-1.5">
280
+ {searchInput}
281
+ <div data-slot="input-meta" className="flex items-start justify-between gap-3 px-1">
282
+ <div
283
+ data-slot="input-helper"
284
+ className={cn(
285
+ "min-w-0 text-xs leading-5",
286
+ errorText ? "text-destructive" : "text-muted-foreground",
287
+ helperClassName
288
+ )}
289
+ >
290
+ {errorText ?? helperText}
291
+ </div>
292
+ {showCharacterCount ? (
293
+ <div
294
+ data-slot="input-count"
295
+ className={cn(
296
+ "shrink-0 text-[11px] font-medium tabular-nums",
297
+ errorText ? "text-destructive" : "text-muted-foreground"
298
+ )}
299
+ >
300
+ {countFormatter?.(currentLength, inputProps.maxLength) ??
301
+ (typeof inputProps.maxLength === "number"
302
+ ? `${currentLength}/${inputProps.maxLength}`
303
+ : currentLength)}
304
+ </div>
305
+ ) : null}
306
+ </div>
307
+ </div>
308
+ )
309
+ }
310
+
213
311
  const {
214
312
  value,
215
313
  defaultValue,
@@ -10,7 +10,7 @@ export type PopoverTriggerProps = PopoverPrimitive.Trigger.Props
10
10
  export type PopoverContentProps = PopoverPrimitive.Popup.Props &
11
11
  Pick<
12
12
  PopoverPrimitive.Positioner.Props,
13
- "align" | "alignOffset" | "side" | "sideOffset"
13
+ "align" | "alignOffset" | "collisionBoundary" | "collisionPadding" | "side" | "sideOffset"
14
14
  >
15
15
  export type PopoverHeaderProps = React.ComponentProps<"div">
16
16
  export type PopoverTitleProps = PopoverPrimitive.Title.Props
@@ -28,6 +28,7 @@ function PopoverContent({
28
28
  className,
29
29
  align = "center",
30
30
  alignOffset = 0,
31
+ collisionPadding = 12,
31
32
  side = "bottom",
32
33
  sideOffset = 4,
33
34
  ...props
@@ -35,16 +36,17 @@ function PopoverContent({
35
36
  return (
36
37
  <PopoverPrimitive.Portal>
37
38
  <PopoverPrimitive.Positioner
38
- align={align}
39
- alignOffset={alignOffset}
40
- side={side}
41
- sideOffset={sideOffset}
42
- className="isolate z-50"
43
- >
39
+ align={align}
40
+ alignOffset={alignOffset}
41
+ collisionPadding={collisionPadding}
42
+ side={side}
43
+ sideOffset={sideOffset}
44
+ className="isolate z-50"
45
+ >
44
46
  <PopoverPrimitive.Popup
45
47
  data-slot="popover-content"
46
48
  className={cn(
47
- "z-50 flex w-80 origin-(--transform-origin) flex-col gap-3 rounded-[var(--aui-card-radius,var(--radius-xl))] border border-[color:var(--aui-card-border,var(--border))] bg-[color:var(--aui-overlay-surface,var(--popover))] p-4 text-sm text-popover-foreground shadow-[var(--aui-popover-shadow,0_18px_42px_rgba(15,23,42,0.16))] outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
49
+ "z-50 flex max-h-[min(var(--available-height),calc(100dvh-1rem))] w-[min(var(--anchor-width),20rem)] min-w-60 max-w-[calc(100vw-1rem)] origin-(--transform-origin) flex-col gap-3 overflow-y-auto rounded-[var(--aui-card-radius,var(--radius-xl))] border border-[color:var(--aui-card-border,var(--border))] bg-[color:var(--aui-overlay-surface,var(--popover))] p-4 text-sm text-popover-foreground shadow-[var(--aui-popover-shadow,0_18px_42px_rgba(15,23,42,0.16))] outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
48
50
  className
49
51
  )}
50
52
  {...props}
@@ -17,7 +17,11 @@ export type RadioGroupProps = Omit<React.ComponentProps<"div">, "onChange"> & {
17
17
  options: RadioGroupOption[]
18
18
  orientation?: "vertical" | "horizontal"
19
19
  size?: "sm" | "default" | "lg"
20
+ invalid?: boolean
21
+ disabled?: boolean
20
22
  itemClassName?: string
23
+ itemLabelClassName?: string
24
+ itemDescriptionClassName?: string
21
25
  }
22
26
 
23
27
  const sizeClassName = {
@@ -34,8 +38,12 @@ function RadioGroup({
34
38
  options,
35
39
  orientation = "vertical",
36
40
  size = "default",
41
+ invalid = false,
42
+ disabled = false,
37
43
  className,
38
44
  itemClassName,
45
+ itemLabelClassName,
46
+ itemDescriptionClassName,
39
47
  ...props
40
48
  }: RadioGroupProps) {
41
49
  const generatedName = React.useId()
@@ -43,39 +51,80 @@ function RadioGroup({
43
51
  const [internalValue, setInternalValue] = React.useState(defaultValue ?? "")
44
52
  const isControlled = value !== undefined
45
53
  const currentValue = isControlled ? value : internalValue
54
+ const itemRefs = React.useRef<Array<HTMLInputElement | null>>([])
55
+ const enabledOptions = options.filter((option) => !option.disabled && !disabled)
46
56
 
47
57
  const setValue = (nextValue: string) => {
48
58
  if (!isControlled) setInternalValue(nextValue)
49
59
  onValueChange?.(nextValue)
50
60
  }
51
61
 
62
+ const focusOption = (nextIndex: number) => {
63
+ const option = enabledOptions[nextIndex]
64
+ if (!option) return
65
+ const optionIndex = options.findIndex((item) => item.value === option.value)
66
+ itemRefs.current[optionIndex]?.focus()
67
+ setValue(option.value)
68
+ }
69
+
70
+ const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event) => {
71
+ if (!["ArrowDown", "ArrowRight", "ArrowUp", "ArrowLeft", "Home", "End"].includes(event.key)) return
72
+ if (enabledOptions.length === 0) return
73
+
74
+ event.preventDefault()
75
+ const currentEnabledIndex = Math.max(
76
+ 0,
77
+ enabledOptions.findIndex((option) => option.value === currentValue)
78
+ )
79
+ if (event.key === "Home") {
80
+ focusOption(0)
81
+ return
82
+ }
83
+ if (event.key === "End") {
84
+ focusOption(enabledOptions.length - 1)
85
+ return
86
+ }
87
+ const direction = event.key === "ArrowDown" || event.key === "ArrowRight" ? 1 : -1
88
+ focusOption((currentEnabledIndex + direction + enabledOptions.length) % enabledOptions.length)
89
+ }
90
+
52
91
  return (
53
92
  <div
54
93
  role="radiogroup"
94
+ aria-invalid={invalid || undefined}
95
+ aria-disabled={disabled || undefined}
55
96
  data-slot="radio-group"
56
97
  data-orientation={orientation}
98
+ data-invalid={invalid || undefined}
57
99
  className={cn("grid gap-2", orientation === "horizontal" && "sm:flex sm:flex-wrap sm:items-center", className)}
100
+ onKeyDown={handleKeyDown}
58
101
  {...props}
59
102
  >
60
- {options.map((option) => {
103
+ {options.map((option, index) => {
61
104
  const checked = option.value === currentValue
105
+ const optionDisabled = disabled || option.disabled
62
106
  return (
63
107
  <label
64
108
  key={option.value}
65
109
  data-slot="radio-group-item"
66
110
  data-checked={checked || undefined}
67
- data-disabled={option.disabled || undefined}
111
+ data-disabled={optionDisabled || undefined}
112
+ data-invalid={invalid || undefined}
68
113
  className={cn(
69
- "group flex cursor-pointer items-start gap-3 rounded-[min(var(--radius-xl),16px)] border border-border/80 bg-background/88 px-3 py-2.5 text-sm transition hover:border-ring/35 hover:bg-accent/60 data-[checked=true]:border-primary/35 data-[checked=true]:bg-primary/8 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-55",
114
+ "group flex cursor-pointer items-start gap-3 rounded-[min(var(--radius-xl),16px)] border border-border/80 bg-background/88 px-3 py-2.5 text-sm transition hover:border-ring/35 hover:bg-accent/60 focus-within:border-ring focus-within:ring-3 focus-within:ring-ring/30 data-[checked=true]:border-primary/35 data-[checked=true]:bg-primary/8 data-[disabled=true]:cursor-not-allowed data-[disabled=true]:opacity-55 data-[invalid=true]:border-destructive/70 data-[invalid=true]:ring-3 data-[invalid=true]:ring-destructive/15",
70
115
  itemClassName
71
116
  )}
72
117
  >
73
118
  <input
119
+ ref={(node) => {
120
+ itemRefs.current[index] = node
121
+ }}
74
122
  type="radio"
75
123
  name={resolvedName}
76
124
  value={option.value}
77
125
  checked={checked}
78
- disabled={option.disabled}
126
+ disabled={optionDisabled}
127
+ aria-invalid={invalid || undefined}
79
128
  className="sr-only"
80
129
  onChange={() => setValue(option.value)}
81
130
  />
@@ -89,8 +138,8 @@ function RadioGroup({
89
138
  <span className="size-1.5 rounded-full bg-primary-foreground opacity-0 transition group-data-[checked=true]:opacity-100" />
90
139
  </span>
91
140
  <span className="min-w-0">
92
- <span className="block font-medium text-foreground">{option.label}</span>
93
- {option.description ? <span className="mt-1 block text-sm leading-6 text-muted-foreground">{option.description}</span> : null}
141
+ <span className={cn("block font-medium text-foreground", itemLabelClassName)}>{option.label}</span>
142
+ {option.description ? <span className={cn("mt-1 block text-sm leading-6 text-muted-foreground", itemDescriptionClassName)}>{option.description}</span> : null}
94
143
  </span>
95
144
  </label>
96
145
  )