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
@@ -2,18 +2,22 @@ import * as React from "react"
2
2
 
3
3
  import { cn } from "@/lib/utils"
4
4
 
5
- export type CalendarSchedulerEvent = {
6
- id: string
7
- title: React.ReactNode
8
- date: string
9
- time?: string
10
- tone?: "default" | "success" | "warning" | "danger"
11
- }
12
-
5
+ export type CalendarSchedulerEvent = {
6
+ id: string
7
+ title: React.ReactNode
8
+ date: string
9
+ time?: string
10
+ tone?: "default" | "success" | "warning" | "danger"
11
+ durationMinutes?: number
12
+ }
13
+
13
14
  export type CalendarSchedulerProps = React.ComponentProps<"div"> & {
14
15
  events: CalendarSchedulerEvent[]
15
16
  days?: string[]
17
+ view?: "day" | "week" | "month"
16
18
  empty?: React.ReactNode
19
+ onCreateEvent?: (date: string) => void
20
+ onEventClick?: (event: CalendarSchedulerEvent) => void
17
21
  }
18
22
 
19
23
  const toneClassName = {
@@ -23,11 +27,11 @@ const toneClassName = {
23
27
  danger: "border-red-200 bg-red-50 text-red-700 dark:border-red-900 dark:bg-red-950 dark:text-red-300",
24
28
  }
25
29
 
26
- function CalendarScheduler({ events, days, empty = "No events scheduled.", className, ...props }: CalendarSchedulerProps) {
30
+ function CalendarScheduler({ events, days, view = "week", empty = "No events scheduled.", onCreateEvent, onEventClick, className, ...props }: CalendarSchedulerProps) {
27
31
  const visibleDays = days ?? Array.from(new Set(events.map((event) => event.date)))
28
32
 
29
33
  return (
30
- <div data-slot="calendar-scheduler" className={cn("grid gap-3", className)} {...props}>
34
+ <div data-slot="calendar-scheduler" data-view={view} className={cn("grid gap-3", view === "month" && "md:grid-cols-2 xl:grid-cols-3", className)} {...props}>
31
35
  {visibleDays.map((day) => (
32
36
  <section key={day} className="rounded-[var(--aui-card-radius,var(--radius-xl))] border border-[color:var(--aui-card-border,var(--border))] bg-card p-4 shadow-[var(--aui-card-shadow,var(--aui-control-shadow,none))]">
33
37
  <div className="mb-3 flex items-center justify-between gap-3">
@@ -41,16 +45,27 @@ function CalendarScheduler({ events, days, empty = "No events scheduled.", class
41
45
  </div>
42
46
  ) : (
43
47
  events.filter((event) => event.date === day).map((event) => (
44
- <div key={event.id} className={cn("rounded-[var(--radius-md)] border px-3 py-2.5 text-sm shadow-sm", toneClassName[event.tone ?? "default"])}>
48
+ <button
49
+ key={event.id}
50
+ type="button"
51
+ className={cn("rounded-[var(--radius-md)] border px-3 py-2.5 text-left text-sm shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40", toneClassName[event.tone ?? "default"])}
52
+ onClick={() => onEventClick?.(event)}
53
+ >
45
54
  <div className="font-medium">{event.title}</div>
46
55
  {event.time && <div className="mt-1 text-xs opacity-70">{event.time}</div>}
47
- </div>
56
+ {event.durationMinutes && <div className="mt-1 text-xs opacity-70">{event.durationMinutes} min</div>}
57
+ </button>
48
58
  ))
49
59
  )}
50
60
  </div>
61
+ {onCreateEvent && (
62
+ <button type="button" className="mt-3 w-full rounded-md border border-dashed px-3 py-2 text-sm text-muted-foreground hover:bg-muted/50" onClick={() => onCreateEvent(day)}>
63
+ Create event
64
+ </button>
65
+ )}
51
66
  </section>
52
67
  ))}
53
- </div>
68
+ </div>
54
69
  )
55
70
  }
56
71
 
@@ -8,44 +8,112 @@ export type DualListItem = {
8
8
  disabled?: boolean
9
9
  }
10
10
 
11
- export type DualListPickerProps = React.ComponentProps<"div"> & {
12
- items: DualListItem[]
13
- picked?: string[]
14
- onPickedChange?: (value: string[]) => void
15
- availableTitle?: React.ReactNode
16
- pickedTitle?: React.ReactNode
17
- }
18
-
19
- function DualListPicker({ items, picked = [], onPickedChange, availableTitle = "Available", pickedTitle = "Selected", className, ...props }: DualListPickerProps) {
20
- const pickedSet = new Set(picked)
21
- const availableItems = items.filter((item) => !pickedSet.has(item.value))
22
- const pickedItems = items.filter((item) => pickedSet.has(item.value))
23
-
24
- function toggle(value: string) {
25
- const next = pickedSet.has(value) ? picked.filter((item) => item !== value) : [...picked, value]
26
- onPickedChange?.(next)
27
- }
28
-
29
- const renderColumn = (title: React.ReactNode, columnItems: DualListItem[]) => (
30
- <div className="min-h-48 rounded-lg border bg-card">
31
- <div className="border-b px-3 py-2 text-sm font-medium">{title}</div>
32
- <div className="grid gap-1 p-2">
33
- {columnItems.map((item) => (
34
- <button key={item.value} type="button" disabled={item.disabled} className="flex items-center justify-between rounded-md px-2 py-1.5 text-left text-sm hover:bg-muted disabled:opacity-50" onClick={() => toggle(item.value)}>
35
- <span>{item.label}</span>
36
- <span className="text-muted-foreground">{pickedSet.has(item.value) ? "" : "+"}</span>
37
- </button>
11
+ export type DualListPickerProps = React.ComponentProps<"div"> & {
12
+ items: DualListItem[]
13
+ picked?: string[]
14
+ onPickedChange?: (value: string[]) => void
15
+ availableTitle?: React.ReactNode
16
+ pickedTitle?: React.ReactNode
17
+ searchPlaceholder?: string
18
+ emptyMessage?: React.ReactNode
19
+ maxPicked?: number
20
+ transferAll?: boolean
21
+ }
22
+
23
+ function DualListPicker({
24
+ items,
25
+ picked = [],
26
+ onPickedChange,
27
+ availableTitle = "Available",
28
+ pickedTitle = "Selected",
29
+ searchPlaceholder = "Search items...",
30
+ emptyMessage = "No items.",
31
+ maxPicked,
32
+ transferAll = true,
33
+ className,
34
+ ...props
35
+ }: DualListPickerProps) {
36
+ const [query, setQuery] = React.useState("")
37
+ const pickedSet = new Set(picked)
38
+ const normalizedQuery = query.trim().toLowerCase()
39
+ const matchesQuery = (item: DualListItem) => {
40
+ if (!normalizedQuery) return true
41
+ return String(item.label).toLowerCase().includes(normalizedQuery) || item.value.toLowerCase().includes(normalizedQuery)
42
+ }
43
+ const availableItems = items.filter((item) => !pickedSet.has(item.value) && matchesQuery(item))
44
+ const pickedItems = items.filter((item) => pickedSet.has(item.value) && matchesQuery(item))
45
+ const maxReached = maxPicked !== undefined && picked.length >= maxPicked
46
+
47
+ function toggle(value: string) {
48
+ const isPicked = pickedSet.has(value)
49
+ if (!isPicked && maxReached) return
50
+ const next = isPicked ? picked.filter((item) => item !== value) : [...picked, value]
51
+ onPickedChange?.(next)
52
+ }
53
+
54
+ function addAll() {
55
+ const next = [...picked]
56
+ for (const item of items) {
57
+ if (item.disabled || pickedSet.has(item.value)) continue
58
+ if (maxPicked !== undefined && next.length >= maxPicked) break
59
+ next.push(item.value)
60
+ }
61
+ onPickedChange?.(next)
62
+ }
63
+
64
+ function removeAll() {
65
+ onPickedChange?.([])
66
+ }
67
+
68
+ const renderColumn = (title: React.ReactNode, columnItems: DualListItem[], mode: "available" | "picked") => (
69
+ <div className="min-h-48 rounded-lg border bg-card">
70
+ <div className="flex items-center justify-between gap-2 border-b px-3 py-2 text-sm font-medium">
71
+ <span>{title}</span>
72
+ <span className="text-xs font-normal text-muted-foreground">{columnItems.length}</span>
73
+ </div>
74
+ <div className="grid gap-1 p-2">
75
+ {columnItems.length === 0 ? (
76
+ <div className="rounded-md border border-dashed px-3 py-6 text-center text-sm text-muted-foreground">{emptyMessage}</div>
77
+ ) : columnItems.map((item) => (
78
+ <button
79
+ key={item.value}
80
+ type="button"
81
+ disabled={item.disabled || (mode === "available" && maxReached)}
82
+ className="flex items-center justify-between rounded-md px-2 py-1.5 text-left text-sm hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring/40 disabled:opacity-50"
83
+ aria-pressed={pickedSet.has(item.value)}
84
+ onClick={() => toggle(item.value)}
85
+ >
86
+ <span>{item.label}</span>
87
+ <span className="text-muted-foreground">{pickedSet.has(item.value) ? "−" : "+"}</span>
88
+ </button>
38
89
  ))}
39
90
  </div>
40
91
  </div>
41
92
  )
42
-
43
- return (
44
- <div data-slot="dual-list-picker" className={cn("grid gap-3 md:grid-cols-2", className)} {...props}>
45
- {renderColumn(availableTitle, availableItems)}
46
- {renderColumn(pickedTitle, pickedItems)}
47
- </div>
48
- )
49
- }
93
+
94
+ return (
95
+ <div data-slot="dual-list-picker" className={cn("grid gap-3", className)} {...props}>
96
+ <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
97
+ <input
98
+ value={query}
99
+ placeholder={searchPlaceholder}
100
+ className="h-9 min-w-0 rounded-md border bg-background px-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring/40 sm:max-w-xs"
101
+ onChange={(event) => setQuery(event.currentTarget.value)}
102
+ />
103
+ {transferAll && (
104
+ <div className="flex gap-2">
105
+ <button type="button" className="rounded-md border px-3 py-1.5 text-sm disabled:opacity-50" disabled={maxReached} onClick={addAll}>Add all</button>
106
+ <button type="button" className="rounded-md border px-3 py-1.5 text-sm disabled:opacity-50" disabled={picked.length === 0} onClick={removeAll}>Remove all</button>
107
+ </div>
108
+ )}
109
+ </div>
110
+ <div className="grid gap-3 md:grid-cols-2">
111
+ {renderColumn(availableTitle, availableItems, "available")}
112
+ {renderColumn(pickedTitle, pickedItems, "picked")}
113
+ </div>
114
+ {maxPicked !== undefined && <div className="text-xs text-muted-foreground">{picked.length} / {maxPicked} selected</div>}
115
+ </div>
116
+ )
117
+ }
50
118
 
51
119
  export { DualListPicker }
@@ -2,14 +2,16 @@ import * as React from "react"
2
2
 
3
3
  import { cn } from "@/lib/utils"
4
4
 
5
- export type RichTextEditorProps = Omit<React.ComponentProps<"div">, "onChange"> & {
6
- value?: string
7
- onValueChange?: (value: string) => void
8
- placeholder?: string
9
- }
10
-
11
- function RichTextEditor({ value, onValueChange, placeholder = "Write something...", className, ...props }: RichTextEditorProps) {
12
- const ref = React.useRef<HTMLDivElement | null>(null)
5
+ export type RichTextEditorProps = Omit<React.ComponentProps<"div">, "onChange"> & {
6
+ value?: string
7
+ onValueChange?: (value: string) => void
8
+ placeholder?: string
9
+ output?: "html" | "text"
10
+ disabled?: boolean
11
+ }
12
+
13
+ function RichTextEditor({ value, onValueChange, placeholder = "Write something...", output = "html", disabled = false, className, ...props }: RichTextEditorProps) {
14
+ const ref = React.useRef<HTMLDivElement | null>(null)
13
15
 
14
16
  React.useEffect(() => {
15
17
  if (ref.current && value !== undefined && ref.current.innerHTML !== value) {
@@ -18,27 +20,28 @@ function RichTextEditor({ value, onValueChange, placeholder = "Write something..
18
20
  }, [value])
19
21
 
20
22
  return (
21
- <div data-slot="rich-text-editor" className={cn("grid gap-2 rounded-lg border bg-background p-2", className)} {...props}>
22
- <div className="flex flex-wrap gap-1 border-b pb-2">
23
+ <div data-slot="rich-text-editor" data-disabled={disabled || undefined} className={cn("grid gap-2 rounded-lg border bg-background p-2", disabled && "opacity-60", className)} {...props}>
24
+ <div className="flex flex-wrap gap-1 border-b pb-2">
23
25
  {[
24
26
  ["bold", "B"],
25
27
  ["italic", "I"],
26
28
  ["underline", "U"],
27
29
  ].map(([command, label]) => (
28
- <button key={command} type="button" className="rounded border px-2 py-1 text-xs font-medium" onClick={() => document.execCommand(command)}>
29
- {label}
30
- </button>
30
+ <button key={command} type="button" disabled={disabled} className="rounded border px-2 py-1 text-xs font-medium disabled:opacity-50" onClick={() => document.execCommand(command)}>
31
+ {label}
32
+ </button>
31
33
  ))}
32
34
  </div>
33
35
  <div
34
- ref={ref}
35
- contentEditable
36
- data-placeholder={placeholder}
37
- className="min-h-32 rounded-md p-2 text-sm outline-none empty:before:text-muted-foreground empty:before:content-[attr(data-placeholder)]"
38
- onInput={(event) => onValueChange?.(event.currentTarget.innerHTML)}
39
- />
40
- </div>
41
- )
42
- }
36
+ ref={ref}
37
+ contentEditable={!disabled}
38
+ aria-disabled={disabled || undefined}
39
+ data-placeholder={placeholder}
40
+ className="min-h-32 rounded-md p-2 text-sm outline-none empty:before:text-muted-foreground empty:before:content-[attr(data-placeholder)]"
41
+ onInput={(event) => onValueChange?.(output === "text" ? event.currentTarget.textContent ?? "" : event.currentTarget.innerHTML)}
42
+ />
43
+ </div>
44
+ )
45
+ }
43
46
 
44
47
  export { RichTextEditor }
@@ -2,38 +2,56 @@ import * as React from "react"
2
2
 
3
3
  import { cn } from "@/lib/utils"
4
4
 
5
- export type TourStep = {
6
- title: React.ReactNode
7
- description?: React.ReactNode
8
- }
5
+ export type TourStep = {
6
+ title: React.ReactNode
7
+ description?: React.ReactNode
8
+ target?: string
9
+ }
9
10
 
10
11
  export type TourProps = React.ComponentProps<"div"> & {
11
12
  steps: TourStep[]
12
- index?: number
13
- onIndexChange?: (index: number) => void
14
- onClose?: () => void
15
- }
16
-
17
- function Tour({ steps, index = 0, onIndexChange, onClose, className, ...props }: TourProps) {
18
- const step = steps[index]
19
- if (!step) return null
20
-
21
- return (
22
- <div data-slot="tour" className={cn("rounded-xl border bg-popover p-4 text-popover-foreground shadow-lg", className)} {...props}>
23
- <div className="grid gap-2">
24
- <div className="font-semibold">{step.title}</div>
25
- {step.description && <div className="text-sm text-muted-foreground">{step.description}</div>}
26
- <div className="flex items-center justify-between gap-3 pt-2">
27
- <span className="text-xs text-muted-foreground">{index + 1} / {steps.length}</span>
28
- <div className="flex gap-2">
29
- <button type="button" className="rounded-md border px-2.5 py-1 text-sm" disabled={index === 0} onClick={() => onIndexChange?.(index - 1)}>Back</button>
30
- {index < steps.length - 1 ? (
31
- <button type="button" className="rounded-md bg-primary px-2.5 py-1 text-sm text-primary-foreground" onClick={() => onIndexChange?.(index + 1)}>Next</button>
32
- ) : (
33
- <button type="button" className="rounded-md bg-primary px-2.5 py-1 text-sm text-primary-foreground" onClick={onClose}>Done</button>
34
- )}
35
- </div>
36
- </div>
13
+ index?: number
14
+ onIndexChange?: (index: number) => void
15
+ onClose?: () => void
16
+ onSkip?: () => void
17
+ onFinish?: () => void
18
+ placement?: "top" | "right" | "bottom" | "left"
19
+ }
20
+
21
+ function Tour({ steps, index = 0, onIndexChange, onClose, onSkip, onFinish, placement = "bottom", className, ...props }: TourProps) {
22
+ const step = steps[index]
23
+ const containerRef = React.useRef<HTMLDivElement | null>(null)
24
+ React.useEffect(() => {
25
+ containerRef.current?.focus()
26
+ }, [index])
27
+
28
+ if (!step) return null
29
+
30
+ return (
31
+ <div
32
+ ref={containerRef}
33
+ data-slot="tour"
34
+ data-placement={placement}
35
+ tabIndex={-1}
36
+ className={cn("rounded-xl border bg-popover p-4 text-popover-foreground shadow-lg outline-none focus-visible:ring-2 focus-visible:ring-ring/40", className)}
37
+ {...props}
38
+ >
39
+ <div className="grid gap-2">
40
+ <div className="font-semibold">{step.title}</div>
41
+ {step.description && <div className="text-sm text-muted-foreground">{step.description}</div>}
42
+ {step.target && <div className="text-xs text-muted-foreground">{step.target}</div>}
43
+ <div className="flex items-center justify-between gap-3 pt-2">
44
+ <span className="text-xs text-muted-foreground">{index + 1} / {steps.length}</span>
45
+ <div className="flex gap-2">
46
+ <button type="button" className="rounded-md border px-2.5 py-1 text-sm" onClick={() => { onSkip?.(); onClose?.() }}>Skip</button>
47
+ <button type="button" className="rounded-md border px-2.5 py-1 text-sm" disabled={index === 0} onClick={() => onIndexChange?.(index - 1)}>Back</button>
48
+ {index < steps.length - 1 ? (
49
+ <button type="button" className="rounded-md bg-primary px-2.5 py-1 text-sm text-primary-foreground" onClick={() => onIndexChange?.(index + 1)}>Next</button>
50
+ ) : (
51
+ <button type="button" className="rounded-md bg-primary px-2.5 py-1 text-sm text-primary-foreground" onClick={() => { onFinish?.(); onClose?.() }}>Done</button>
52
+ )}
53
+ </div>
54
+ </div>
37
55
  </div>
38
56
  </div>
39
57
  )
@@ -5,11 +5,15 @@ export type CommandBarProps = React.ComponentProps<"div"> & {
5
5
  open?: boolean
6
6
  onOpenChange?: (open: boolean) => void
7
7
  position?: "bottom" | "top"
8
+ grouped?: boolean
9
+ label?: React.ReactNode
8
10
  }
9
11
 
10
12
  function CommandBar({
11
13
  open = true,
12
14
  position = "bottom",
15
+ grouped = false,
16
+ label,
13
17
  children,
14
18
  className,
15
19
  ...props
@@ -22,10 +26,12 @@ function CommandBar({
22
26
  className={cn(
23
27
  "fixed left-1/2 z-50 flex -translate-x-1/2 items-center gap-2 rounded-full border bg-background/95 px-4 py-2 shadow-lg backdrop-blur supports-[backdrop-filter]:bg-background/60",
24
28
  position === "bottom" ? "bottom-6" : "top-6",
29
+ grouped && "gap-3 rounded-[28px] px-3 py-2.5",
25
30
  className
26
31
  )}
27
32
  {...props}
28
33
  >
34
+ {label ? <span className="text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground">{label}</span> : null}
29
35
  {children}
30
36
  </div>
31
37
  )
@@ -3,7 +3,6 @@ import { component, createShowcaseDemoRegistry } from "@/showcase/create-demo"
3
3
  export const navigationShowcaseDemoRegistry = createShowcaseDemoRegistry([
4
4
  component("pagination", "Pagination", "navigation", "Controlled page navigation with edge buttons and active state."),
5
5
  component("nav-tabs", "NavTabs", "navigation", "Navigation tabs for switching related document sections."),
6
- component("anchor-nav", "AnchorNav", "navigation", "Section jump navigation for long detail pages."),
7
6
  component("page-tabs", "PageTabs", "navigation", "Top-level page tab strip for route-sized sections."),
8
7
  component("stepper-tabs", "StepperTabs", "navigation", "Step-like tabs for setup and onboarding progress."),
9
8
  ])
@@ -1,6 +1,7 @@
1
- import * as React from "react"
2
-
3
- import { cn } from "@/lib/utils"
1
+ import * as React from "react"
2
+
3
+ import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
4
+ import { cn } from "@/lib/utils"
4
5
 
5
6
  export type NavTabItem = {
6
7
  label: React.ReactNode
@@ -24,37 +25,45 @@ const sizeClassName = {
24
25
  lg: "h-11 px-5 text-base",
25
26
  }
26
27
 
27
- function NavTabs({ items, value, onValueChange, size = "default", fullWidth = false, className, ...props }: NavTabsProps) {
28
- return (
29
- <div data-slot="nav-tabs" className={cn("inline-flex rounded-[var(--radius-xl)] border border-border/80 bg-muted/45 p-1", fullWidth && "w-full", className)} {...props}>
30
- {items.map((item) => {
31
- const active = item.value === value
32
- const content = (
28
+ function NavTabs({ items, value, onValueChange, size = "default", fullWidth = false, className, ...props }: NavTabsProps) {
29
+ return (
30
+ <Tabs
31
+ value={value}
32
+ onValueChange={(nextValue) => onValueChange?.(String(nextValue))}
33
+ data-slot="nav-tabs"
34
+ className={cn("min-w-0", fullWidth && "w-full", className)}
35
+ {...props}
36
+ >
37
+ <TabsList data-slot="nav-tabs-list" variant="pills" overflow="scroll" className={cn(fullWidth && "w-full")}>
38
+ {items.map((item) => {
39
+ const active = item.value === value
40
+ const content = (
33
41
  <>
34
42
  {item.icon ? <span className="[&_svg]:size-4">{item.icon}</span> : null}
35
43
  <span className="truncate">{item.label}</span>
36
44
  </>
37
45
  )
38
46
 
39
- const itemClassName = cn(
40
- "inline-flex items-center justify-center gap-2 rounded-[calc(var(--radius-xl)-4px)] font-medium text-muted-foreground transition hover:text-foreground disabled:pointer-events-none disabled:opacity-50",
41
- sizeClassName[size],
42
- fullWidth && "flex-1",
43
- active && "bg-background text-foreground shadow-sm"
44
- )
45
-
46
- return item.href ? (
47
- <a key={item.value} href={item.href} aria-current={active ? "page" : undefined} className={itemClassName}>
48
- {content}
49
- </a>
50
- ) : (
51
- <button key={item.value} type="button" disabled={item.disabled} className={itemClassName} onClick={() => onValueChange?.(item.value)}>
52
- {content}
53
- </button>
54
- )
55
- })}
56
- </div>
57
- )
58
- }
47
+ const itemClassName = cn(
48
+ "min-w-0 disabled:pointer-events-none disabled:opacity-50",
49
+ sizeClassName[size],
50
+ fullWidth && "flex-1",
51
+ active && "bg-background text-foreground shadow-sm"
52
+ )
53
+
54
+ return item.href ? (
55
+ <TabsTrigger key={item.value} value={item.value} render={<a href={item.href} aria-current={active ? "page" : undefined} className={itemClassName} />}>
56
+ {content}
57
+ </TabsTrigger>
58
+ ) : (
59
+ <TabsTrigger key={item.value} value={item.value} disabled={item.disabled} className={itemClassName} onClick={() => onValueChange?.(item.value)}>
60
+ {content}
61
+ </TabsTrigger>
62
+ )
63
+ })}
64
+ </TabsList>
65
+ </Tabs>
66
+ )
67
+ }
59
68
 
60
69
  export { NavTabs }
@@ -1,7 +1,8 @@
1
1
  import * as React from "react"
2
2
 
3
- import { Badge } from "@/components/ui/badge"
4
- import { cn } from "@/lib/utils"
3
+ import { Badge } from "@/components/ui/badge"
4
+ import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
5
+ import { cn } from "@/lib/utils"
5
6
 
6
7
  export type PageTabItem<TValue extends string = string> = {
7
8
  value: TValue
@@ -30,40 +31,50 @@ function PageTabs<TValue extends string = string>({
30
31
  ...props
31
32
  }: PageTabsProps<TValue>) {
32
33
  const visibleItems = items.filter((item) => !item.hidden)
34
+ const handleValueChange = (nextValue: unknown) => {
35
+ const nextItem = visibleItems.find((item) => item.value === nextValue)
36
+ if (nextItem) {
37
+ onValueChange?.(nextItem.value, nextItem)
38
+ }
39
+ }
33
40
 
34
41
  return (
35
- <div
42
+ <Tabs
43
+ value={value}
44
+ onValueChange={handleValueChange}
36
45
  data-slot="page-tabs"
37
46
  data-variant={variant}
38
47
  className={cn(
39
- "flex min-w-0 flex-wrap gap-1.5 border-b border-border/70",
40
- variant === "pills" && "rounded-full border border-border/75 bg-muted/22 p-1 shadow-[0_1px_0_rgba(255,255,255,0.04)]",
41
- variant === "cards" && "gap-2 border-b-0",
42
- variant !== "underline" && "border-b-0",
48
+ "min-w-0",
43
49
  className
44
50
  )}
45
51
  {...props}
46
52
  >
53
+ <TabsList
54
+ data-slot="page-tabs-list"
55
+ variant={variant === "underline" ? "underline" : "pills"}
56
+ overflow="scroll"
57
+ className={cn(
58
+ "w-full",
59
+ variant === "cards" && "gap-2 border-0 bg-transparent p-0 shadow-none"
60
+ )}
61
+ >
47
62
  {visibleItems.map((item) => {
48
63
  const active = item.value === value
49
64
  return (
50
- <button
51
- key={item.value}
52
- type="button"
53
- disabled={item.disabled}
54
- data-slot="page-tab"
55
- data-active={active || undefined}
65
+ <TabsTrigger
66
+ key={item.value}
67
+ disabled={item.disabled}
68
+ value={item.value}
69
+ data-slot="page-tab"
70
+ data-active={active || undefined}
56
71
  className={cn(
57
- "inline-flex min-w-0 items-center gap-2 rounded-full px-3 text-sm font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 [&_svg]:size-4",
72
+ "min-w-0 px-3 disabled:pointer-events-none disabled:opacity-50",
58
73
  size === "sm" ? "h-8" : "h-10",
59
- variant === "underline" && "rounded-none border-b-2 border-transparent px-1 text-muted-foreground hover:text-foreground",
60
- variant === "underline" && active && "border-primary text-foreground",
61
- variant === "pills" && "text-muted-foreground hover:bg-background/72 hover:text-foreground",
62
- variant === "pills" && active && "bg-primary text-primary-foreground hover:bg-primary/90 hover:text-primary-foreground",
74
+ variant === "underline" && "px-1",
63
75
  variant === "cards" && "rounded-[var(--radius-2xl)] border border-border/75 bg-card/96 text-muted-foreground shadow-sm ring-1 ring-foreground/4 hover:border-primary/28 hover:text-foreground",
64
76
  variant === "cards" && active && "border-primary/50 bg-primary/7 text-foreground"
65
77
  )}
66
- onClick={() => onValueChange?.(item.value, item)}
67
78
  >
68
79
  {item.icon}
69
80
  <span className="truncate">{item.label}</span>
@@ -72,11 +83,12 @@ function PageTabs<TValue extends string = string>({
72
83
  {item.badge}
73
84
  </Badge>
74
85
  )}
75
- </button>
86
+ </TabsTrigger>
76
87
  )
77
88
  })}
78
- </div>
79
- )
80
- }
89
+ </TabsList>
90
+ </Tabs>
91
+ )
92
+ }
81
93
 
82
94
  export { PageTabs }