banhaten 0.3.0 → 0.5.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 (348) hide show
  1. package/CHANGELOG.md +139 -73
  2. package/CONTRIBUTING.md +46 -44
  3. package/README.md +192 -190
  4. package/SECURITY.md +15 -15
  5. package/banhaten.config.example.json +11 -11
  6. package/docs/design-spacing.md +13 -0
  7. package/docs/design-system/README.md +22 -20
  8. package/docs/design-system/adoption-quality-remediation.md +87 -87
  9. package/docs/design-system/agent-usage.md +13 -13
  10. package/docs/design-system/appearance-presets.md +189 -189
  11. package/docs/design-system/appearances/default.md +94 -94
  12. package/docs/design-system/appearances/rounded.md +95 -95
  13. package/docs/design-system/appearances/sharp.md +95 -95
  14. package/docs/design-system/component-docs-pattern.md +81 -81
  15. package/docs/design-system/component-implementation-ownership-audit.md +245 -244
  16. package/docs/design-system/component-quality-audit-2026-08-20.md +225 -223
  17. package/docs/design-system/component-showcase-consistency-report.md +219 -219
  18. package/docs/design-system/component-token-consistency-audit.md +173 -173
  19. package/docs/design-system/components/README.md +90 -76
  20. package/docs/design-system/components/accordion.md +53 -53
  21. package/docs/design-system/components/activity-feed.md +94 -94
  22. package/docs/design-system/components/activity-heatmap.md +57 -57
  23. package/docs/design-system/components/agent-input.md +85 -0
  24. package/docs/design-system/components/alert-dialog.md +72 -72
  25. package/docs/design-system/components/alert.md +98 -98
  26. package/docs/design-system/components/approval-card.md +134 -0
  27. package/docs/design-system/components/aspect-ratio.md +45 -45
  28. package/docs/design-system/components/attribute.md +89 -89
  29. package/docs/design-system/components/autocomplete.md +75 -75
  30. package/docs/design-system/components/avatar.md +54 -54
  31. package/docs/design-system/components/badge.md +54 -54
  32. package/docs/design-system/components/banner.md +87 -87
  33. package/docs/design-system/components/breadcrumbs.md +177 -176
  34. package/docs/design-system/components/button-group.md +98 -98
  35. package/docs/design-system/components/button.md +83 -80
  36. package/docs/design-system/components/card.md +88 -88
  37. package/docs/design-system/components/carousel.md +46 -46
  38. package/docs/design-system/components/catalog-components.md +47 -47
  39. package/docs/design-system/components/chart.md +95 -24
  40. package/docs/design-system/components/checkbox.md +54 -54
  41. package/docs/design-system/components/collapsible.md +67 -53
  42. package/docs/design-system/components/command.md +62 -62
  43. package/docs/design-system/components/context-menu.md +46 -46
  44. package/docs/design-system/components/date-picker.md +81 -79
  45. package/docs/design-system/components/divider.md +102 -102
  46. package/docs/design-system/components/empty-state.md +56 -56
  47. package/docs/design-system/components/field.md +70 -70
  48. package/docs/design-system/components/file-upload.md +187 -187
  49. package/docs/design-system/components/hover-card.md +48 -48
  50. package/docs/design-system/components/icons.md +48 -48
  51. package/docs/design-system/components/inline-citations.md +93 -0
  52. package/docs/design-system/components/input-group.md +58 -58
  53. package/docs/design-system/components/input-otp.md +56 -56
  54. package/docs/design-system/components/input.md +117 -61
  55. package/docs/design-system/components/item.md +59 -57
  56. package/docs/design-system/components/kbd.md +54 -49
  57. package/docs/design-system/components/label.md +49 -49
  58. package/docs/design-system/components/menu.md +71 -61
  59. package/docs/design-system/components/menubar.md +47 -47
  60. package/docs/design-system/components/modal.md +105 -105
  61. package/docs/design-system/components/native-select.md +54 -54
  62. package/docs/design-system/components/navigation-menu.md +50 -50
  63. package/docs/design-system/components/onboarding-step-list-item.md +82 -82
  64. package/docs/design-system/components/page-header.md +93 -86
  65. package/docs/design-system/components/pagination.md +57 -57
  66. package/docs/design-system/components/popover.md +60 -60
  67. package/docs/design-system/components/progress-slider.md +50 -50
  68. package/docs/design-system/components/progress.md +76 -76
  69. package/docs/design-system/components/radio-card.md +51 -51
  70. package/docs/design-system/components/radio-group.md +57 -57
  71. package/docs/design-system/components/resizable.md +44 -44
  72. package/docs/design-system/components/rolling-count.md +61 -0
  73. package/docs/design-system/components/scroll-area.md +51 -51
  74. package/docs/design-system/components/segmented-control.md +54 -54
  75. package/docs/design-system/components/select.md +68 -62
  76. package/docs/design-system/components/sheet.md +67 -67
  77. package/docs/design-system/components/shimmer-text.md +67 -0
  78. package/docs/design-system/components/sidebar.md +127 -76
  79. package/docs/design-system/components/skeleton.md +75 -75
  80. package/docs/design-system/components/slideout.md +65 -65
  81. package/docs/design-system/components/slider.md +63 -63
  82. package/docs/design-system/components/social-button.md +50 -50
  83. package/docs/design-system/components/spinner.md +62 -62
  84. package/docs/design-system/components/steps.md +65 -65
  85. package/docs/design-system/components/streaming-text.md +82 -0
  86. package/docs/design-system/components/table.md +419 -414
  87. package/docs/design-system/components/tabs.md +59 -55
  88. package/docs/design-system/components/tag.md +80 -80
  89. package/docs/design-system/components/task-list.md +95 -0
  90. package/docs/design-system/components/textarea.md +50 -50
  91. package/docs/design-system/components/thinking-reasoning.md +72 -0
  92. package/docs/design-system/components/thinking-state.md +67 -0
  93. package/docs/design-system/components/timeline.md +83 -83
  94. package/docs/design-system/components/toast.md +58 -58
  95. package/docs/design-system/components/toggle.md +81 -81
  96. package/docs/design-system/components/toolbar.md +92 -87
  97. package/docs/design-system/components/tooltip.md +94 -92
  98. package/docs/design-system/components/typography.md +18 -18
  99. package/docs/design-system/density-and-elevation.md +65 -61
  100. package/docs/design-system/design-system-test-missing-items.md +368 -368
  101. package/docs/design-system/direction-and-localization.md +23 -23
  102. package/docs/design-system/form-recipes.md +73 -73
  103. package/docs/design-system/gap-promotion-policy.md +21 -21
  104. package/docs/design-system/icons.md +74 -69
  105. package/docs/design-system/installation.md +70 -68
  106. package/docs/design-system/launch-comparison-shadcn.md +98 -98
  107. package/docs/design-system/registry-and-cli.md +64 -64
  108. package/docs/design-system/release-policy.md +30 -30
  109. package/docs/design-system/roadmap.md +14 -14
  110. package/docs/design-system/support-matrix.md +23 -23
  111. package/docs/design-system/tabs.md +54 -53
  112. package/docs/design-system/template-gap-audit.md +32 -0
  113. package/docs/design-system/templates.md +59 -0
  114. package/docs/design-system/token-governance.md +72 -60
  115. package/package.json +98 -98
  116. package/registry/component-contract.json +40 -40
  117. package/registry/components/accordion.tsx +155 -155
  118. package/registry/components/agent-input-parts.tsx +552 -0
  119. package/registry/components/agent-input-state.ts +156 -0
  120. package/registry/components/agent-input.css +307 -0
  121. package/registry/components/agent-input.tsx +382 -0
  122. package/registry/components/alert-dialog.tsx +297 -297
  123. package/registry/components/alert.tsx +293 -293
  124. package/registry/components/approval-card.css +409 -0
  125. package/registry/components/approval-card.tsx +401 -0
  126. package/registry/components/approval-frame.tsx +108 -0
  127. package/registry/components/approval-questions.tsx +559 -0
  128. package/registry/components/aspect-ratio.tsx +30 -30
  129. package/registry/components/attribute.tsx +454 -448
  130. package/registry/components/autocomplete.tsx +598 -651
  131. package/registry/components/avatar.tsx +385 -381
  132. package/registry/components/badge.tsx +629 -629
  133. package/registry/components/button-group.tsx +565 -565
  134. package/registry/components/button.tsx +127 -123
  135. package/registry/components/card.tsx +638 -638
  136. package/registry/components/carousel.tsx +296 -296
  137. package/registry/components/chart-block-data.ts +177 -0
  138. package/registry/components/chart-block.css +171 -0
  139. package/registry/components/chart-block.tsx +260 -0
  140. package/registry/components/chart-interactions.ts +123 -0
  141. package/registry/components/chart-options.cartesian.ts +162 -0
  142. package/registry/components/chart-options.paint.ts +99 -0
  143. package/registry/components/chart-options.parts.ts +72 -0
  144. package/registry/components/chart-options.radial.ts +109 -0
  145. package/registry/components/chart-options.ts +44 -0
  146. package/registry/components/chart-options.types.ts +67 -0
  147. package/registry/components/chart.tsx +203 -203
  148. package/registry/components/checkbox.tsx +247 -247
  149. package/registry/components/collapsible.tsx +109 -69
  150. package/registry/components/command.tsx +208 -208
  151. package/registry/components/context-menu.tsx +236 -236
  152. package/registry/components/data-chart.tsx +40 -0
  153. package/registry/components/date-picker.tsx +1289 -1277
  154. package/registry/components/echart-theme.ts +246 -0
  155. package/registry/components/echart.css +49 -0
  156. package/registry/components/echart.tsx +178 -0
  157. package/registry/components/expanded/ActivityFeed.tsx +227 -227
  158. package/registry/components/expanded/ActivityHeatmap.tsx +64 -64
  159. package/registry/components/expanded/Banner.tsx +179 -179
  160. package/registry/components/expanded/Breadcrumbs.tsx +131 -131
  161. package/registry/components/expanded/CatalogComponentsShowcase.tsx +205 -205
  162. package/registry/components/expanded/CatalogDivider.tsx +49 -49
  163. package/registry/components/expanded/EmptyState.tsx +155 -155
  164. package/registry/components/expanded/FileUpload.tsx +543 -543
  165. package/registry/components/expanded/OnboardingStepListItem.tsx +60 -59
  166. package/registry/components/expanded/PageHeader.tsx +179 -166
  167. package/registry/components/expanded/Slideout.tsx +108 -108
  168. package/registry/components/expanded/Steps.tsx +402 -402
  169. package/registry/components/expanded/Table.tsx +1092 -1071
  170. package/registry/components/expanded/Timeline.tsx +203 -203
  171. package/registry/components/expanded/activityFeed.css +248 -248
  172. package/registry/components/expanded/activityHeatmap.css +66 -66
  173. package/registry/components/expanded/banner.css +260 -255
  174. package/registry/components/expanded/breadcrumbs.css +140 -140
  175. package/registry/components/expanded/catalogComponentsShowcase.css +87 -87
  176. package/registry/components/expanded/divider.css +75 -75
  177. package/registry/components/expanded/emptyState.css +111 -111
  178. package/registry/components/expanded/fileUpload.css +457 -457
  179. package/registry/components/expanded/onboardingStepListItem.css +135 -126
  180. package/registry/components/expanded/pageHeader.css +248 -290
  181. package/registry/components/expanded/slideout.css +276 -276
  182. package/registry/components/expanded/steps.css +356 -356
  183. package/registry/components/expanded/table.css +606 -603
  184. package/registry/components/expanded/timeline.css +286 -286
  185. package/registry/components/field.tsx +283 -283
  186. package/registry/components/hover-card.tsx +48 -48
  187. package/registry/components/inline-citations.css +126 -0
  188. package/registry/components/inline-citations.tsx +292 -0
  189. package/registry/components/input-content.ts +107 -107
  190. package/registry/components/input-group.tsx +130 -130
  191. package/registry/components/input-otp.tsx +584 -584
  192. package/registry/components/input.tsx +990 -972
  193. package/registry/components/item.tsx +189 -189
  194. package/registry/components/kbd.tsx +246 -151
  195. package/registry/components/label.tsx +78 -78
  196. package/registry/components/menu.tsx +978 -986
  197. package/registry/components/menubar.tsx +226 -226
  198. package/registry/components/modal.tsx +872 -872
  199. package/registry/components/native-select.tsx +205 -205
  200. package/registry/components/navigation-menu.tsx +171 -171
  201. package/registry/components/pagination.css +36 -36
  202. package/registry/components/pagination.tsx +560 -555
  203. package/registry/components/popover.tsx +338 -338
  204. package/registry/components/progress-slider.tsx +216 -216
  205. package/registry/components/radio-card.tsx +676 -677
  206. package/registry/components/radio-group.tsx +570 -570
  207. package/registry/components/resizable.tsx +108 -108
  208. package/registry/components/rolling-count.css +37 -0
  209. package/registry/components/rolling-count.tsx +110 -0
  210. package/registry/components/scroll-area.tsx +91 -91
  211. package/registry/components/segmented-control.tsx +87 -87
  212. package/registry/components/select-content.tsx +218 -218
  213. package/registry/components/select.tsx +937 -932
  214. package/registry/components/sheet.tsx +305 -305
  215. package/registry/components/shimmer-text.css +69 -0
  216. package/registry/components/shimmer-text.tsx +43 -0
  217. package/registry/components/sidebar.tsx +1433 -358
  218. package/registry/components/skeleton.css +54 -54
  219. package/registry/components/skeleton.tsx +482 -482
  220. package/registry/components/slider.tsx +380 -380
  221. package/registry/components/social-button.tsx +387 -387
  222. package/registry/components/spinner.tsx +78 -78
  223. package/registry/components/streaming-text.css +45 -0
  224. package/registry/components/streaming-text.tsx +165 -0
  225. package/registry/components/table-elements.tsx +128 -128
  226. package/registry/components/tabs.css +222 -218
  227. package/registry/components/tabs.tsx +241 -241
  228. package/registry/components/tag.tsx +423 -423
  229. package/registry/components/task-list.css +328 -0
  230. package/registry/components/task-list.tsx +429 -0
  231. package/registry/components/textarea.tsx +610 -610
  232. package/registry/components/thinking-reasoning.css +178 -0
  233. package/registry/components/thinking-reasoning.tsx +253 -0
  234. package/registry/components/thinking-state.css +8 -0
  235. package/registry/components/thinking-state.tsx +46 -0
  236. package/registry/components/toast.tsx +136 -136
  237. package/registry/components/toggle.tsx +256 -256
  238. package/registry/components/toolbar.tsx +539 -539
  239. package/registry/components/tooltip.tsx +433 -431
  240. package/registry/examples/agent-input-demo.tsx +90 -0
  241. package/registry/examples/alert-demo.tsx +34 -34
  242. package/registry/examples/alert-dialog-demo.tsx +42 -42
  243. package/registry/examples/approval-card-demo.tsx +83 -0
  244. package/registry/examples/aspect-ratio-demo.tsx +11 -11
  245. package/registry/examples/attribute-demo.tsx +65 -65
  246. package/registry/examples/autocomplete-demo.tsx +109 -109
  247. package/registry/examples/avatar-demo.tsx +132 -132
  248. package/registry/examples/badge-demo.tsx +69 -69
  249. package/registry/examples/button-demo.tsx +86 -83
  250. package/registry/examples/button-group-demo.tsx +63 -63
  251. package/registry/examples/card-demo.tsx +86 -86
  252. package/registry/examples/carousel-demo.tsx +43 -43
  253. package/registry/examples/chart-block-demo.tsx +5 -0
  254. package/registry/examples/chart-demo.tsx +18 -33
  255. package/registry/examples/checkbox-demo.tsx +62 -62
  256. package/registry/examples/collapsible-demo.tsx +16 -16
  257. package/registry/examples/collection-filter-bar-demo.tsx +135 -135
  258. package/registry/examples/command-demo.tsx +42 -42
  259. package/registry/examples/command-palette-demo.tsx +235 -236
  260. package/registry/examples/context-menu-demo.tsx +29 -29
  261. package/registry/examples/control-density-contract-demo.tsx +65 -61
  262. package/registry/examples/date-picker-demo.tsx +127 -127
  263. package/registry/examples/divider-demo.tsx +17 -17
  264. package/registry/examples/expanded/activity-heatmap-demo.tsx +29 -29
  265. package/registry/examples/expanded/banner-demo.tsx +48 -48
  266. package/registry/examples/expanded/breadcrumbs-demo.tsx +59 -59
  267. package/registry/examples/expanded/empty-state-demo.tsx +39 -39
  268. package/registry/examples/expanded/file-upload-demo.tsx +60 -60
  269. package/registry/examples/expanded/onboarding-step-demo.tsx +11 -11
  270. package/registry/examples/expanded/slideout-demo.tsx +15 -15
  271. package/registry/examples/expanded/steps-demo.tsx +29 -29
  272. package/registry/examples/expanded/tabs-demo.tsx +13 -13
  273. package/registry/examples/expanded/timeline-demo.tsx +18 -18
  274. package/registry/examples/field-demo.tsx +51 -51
  275. package/registry/examples/hover-card-demo.tsx +23 -23
  276. package/registry/examples/inline-citations-demo.tsx +31 -0
  277. package/registry/examples/input-actions-demo.tsx +36 -0
  278. package/registry/examples/input-demo.tsx +87 -87
  279. package/registry/examples/input-group-demo.tsx +16 -16
  280. package/registry/examples/input-otp-demo.tsx +72 -72
  281. package/registry/examples/item-demo.tsx +46 -46
  282. package/registry/examples/kbd-demo.tsx +12 -11
  283. package/registry/examples/label-demo.tsx +20 -20
  284. package/registry/examples/menu-demo.tsx +122 -122
  285. package/registry/examples/menubar-demo.tsx +34 -34
  286. package/registry/examples/modal-demo.tsx +74 -74
  287. package/registry/examples/native-select-demo.tsx +16 -16
  288. package/registry/examples/navigation-menu-demo.tsx +29 -29
  289. package/registry/examples/pagination-demo.tsx +20 -20
  290. package/registry/examples/popover-demo.tsx +547 -546
  291. package/registry/examples/progress-demo.tsx +37 -37
  292. package/registry/examples/progress-slider-demo.tsx +29 -29
  293. package/registry/examples/radio-card-demo.tsx +51 -51
  294. package/registry/examples/radio-group-demo.tsx +62 -62
  295. package/registry/examples/resizable-demo.tsx +22 -22
  296. package/registry/examples/results-toolbar-demo.tsx +44 -44
  297. package/registry/examples/rolling-count-demo.tsx +39 -0
  298. package/registry/examples/scroll-area-demo.tsx +15 -15
  299. package/registry/examples/segmented-control-demo.tsx +39 -39
  300. package/registry/examples/select-demo.tsx +87 -87
  301. package/registry/examples/sheet-demo.tsx +47 -47
  302. package/registry/examples/shimmer-text-demo.tsx +20 -0
  303. package/registry/examples/sidebar-demo.tsx +101 -57
  304. package/registry/examples/slider-demo.tsx +31 -31
  305. package/registry/examples/social-button-demo.tsx +61 -61
  306. package/registry/examples/spinner-demo.tsx +59 -59
  307. package/registry/examples/streaming-text-demo.tsx +28 -0
  308. package/registry/examples/tabs-demo.tsx +13 -13
  309. package/registry/examples/tag-demo.tsx +29 -29
  310. package/registry/examples/task-list-demo.tsx +74 -0
  311. package/registry/examples/textarea-demo.tsx +79 -79
  312. package/registry/examples/thinking-reasoning-demo.tsx +74 -0
  313. package/registry/examples/thinking-state-demo.tsx +13 -0
  314. package/registry/examples/toast-demo.tsx +35 -35
  315. package/registry/examples/toggle-demo.tsx +59 -59
  316. package/registry/examples/tooltip-demo.tsx +115 -115
  317. package/registry/guidance/USAGE.md +27 -27
  318. package/registry/guidance/charts.LICENSE.txt +24 -0
  319. package/registry/hooks/use-controllable-state.ts +33 -0
  320. package/registry/hooks/use-direction.ts +207 -207
  321. package/registry/hooks/use-listbox-navigation.ts +73 -0
  322. package/registry/hooks/use-motion-end.ts +55 -0
  323. package/registry/hooks/use-reduced-motion.ts +28 -0
  324. package/registry/index.json +1634 -184
  325. package/registry/styles/globals.css +1462 -1570
  326. package/registry.json +364 -10
  327. package/schema/config.schema.json +51 -51
  328. package/schema/registry.schema.json +194 -190
  329. package/schema/tokens.schema.json +167 -163
  330. package/src/cli/command-line.js +194 -194
  331. package/src/cli/config-editors.js +9 -9
  332. package/src/cli/doctor.js +399 -399
  333. package/src/cli/file-transaction.js +302 -295
  334. package/src/cli/global-css.js +153 -153
  335. package/src/cli/index.js +1002 -1009
  336. package/src/cli/install-plan.js +592 -592
  337. package/src/cli/install-receipt.js +171 -171
  338. package/src/cli/jsonc.js +203 -203
  339. package/src/cli/package-install-state.js +254 -254
  340. package/src/cli/package-manager.js +238 -238
  341. package/src/cli/package-plan.js +185 -185
  342. package/src/cli/package-version.js +97 -97
  343. package/src/cli/registry-query.js +207 -207
  344. package/src/cli/reporting.js +55 -55
  345. package/src/cli/schema-validation.js +19 -19
  346. package/src/cli/source-scanner.js +686 -686
  347. package/src/cli/vite-config.js +478 -478
  348. package/tokens/banhaten.tokens.json +458 -224
@@ -1,59 +1,59 @@
1
- import type * as React from "react"
2
-
3
- import { DynamicSpinner, Spinner } from "@/components/ui/spinner"
4
-
5
- export function SpinnerDemo() {
6
- return (
7
- <div className="grid gap-[var(--bh-space-5xl-24)]">
8
- <div className="flex flex-wrap items-center gap-[var(--bh-space-5xl-24)]">
9
- <Spinner
10
- className="text-primary"
11
- style={{ "--bh-spinner-size": "var(--bh-space-3xl-16)" } as React.CSSProperties}
12
- />
13
- <Spinner
14
- className="text-success"
15
- style={{ "--bh-spinner-size": "var(--bh-space-4xl-20)" } as React.CSSProperties}
16
- />
17
- <Spinner
18
- className="text-danger"
19
- style={{ "--bh-spinner-size": "var(--bh-space-5xl-24)" } as React.CSSProperties}
20
- />
21
- <DynamicSpinner
22
- className="text-primary"
23
- style={{ "--bh-spinner-size": "var(--bh-space-3xl-16)" } as React.CSSProperties}
24
- />
25
- <DynamicSpinner
26
- className="text-success"
27
- style={{ "--bh-spinner-size": "var(--bh-space-4xl-20)" } as React.CSSProperties}
28
- />
29
- <DynamicSpinner
30
- className="text-danger"
31
- style={{ "--bh-spinner-size": "var(--bh-space-5xl-24)" } as React.CSSProperties}
32
- />
33
- </div>
34
-
35
- <div className="flex flex-wrap items-center gap-[var(--bh-space-xl-12)]">
36
- <div
37
- className="inline-flex items-center gap-[var(--bh-space-md-8)] text-sm text-muted-foreground"
38
- role="status"
39
- >
40
- <Spinner
41
- className="text-current"
42
- style={{ "--bh-spinner-size": "calc(var(--bh-space-2xl-14) + var(--bh-space-xs-4))" } as React.CSSProperties}
43
- />
44
- Loading
45
- </div>
46
- <div
47
- className="inline-flex items-center gap-[var(--bh-space-md-8)] text-sm text-muted-foreground"
48
- role="status"
49
- >
50
- <DynamicSpinner
51
- className="text-current"
52
- style={{ "--bh-spinner-size": "calc(var(--bh-space-2xl-14) + var(--bh-space-xs-4))" } as React.CSSProperties}
53
- />
54
- Syncing
55
- </div>
56
- </div>
57
- </div>
58
- )
59
- }
1
+ import type * as React from "react"
2
+
3
+ import { DynamicSpinner, Spinner } from "@/components/ui/spinner"
4
+
5
+ export function SpinnerDemo() {
6
+ return (
7
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
8
+ <div className="flex flex-wrap items-center gap-[var(--bh-space-5xl-24)]">
9
+ <Spinner
10
+ className="text-primary"
11
+ style={{ "--bh-spinner-size": "var(--bh-space-3xl-16)" } as React.CSSProperties}
12
+ />
13
+ <Spinner
14
+ className="text-success"
15
+ style={{ "--bh-spinner-size": "var(--bh-space-4xl-20)" } as React.CSSProperties}
16
+ />
17
+ <Spinner
18
+ className="text-danger"
19
+ style={{ "--bh-spinner-size": "var(--bh-space-5xl-24)" } as React.CSSProperties}
20
+ />
21
+ <DynamicSpinner
22
+ className="text-primary"
23
+ style={{ "--bh-spinner-size": "var(--bh-space-3xl-16)" } as React.CSSProperties}
24
+ />
25
+ <DynamicSpinner
26
+ className="text-success"
27
+ style={{ "--bh-spinner-size": "var(--bh-space-4xl-20)" } as React.CSSProperties}
28
+ />
29
+ <DynamicSpinner
30
+ className="text-danger"
31
+ style={{ "--bh-spinner-size": "var(--bh-space-5xl-24)" } as React.CSSProperties}
32
+ />
33
+ </div>
34
+
35
+ <div className="flex flex-wrap items-center gap-[var(--bh-space-xl-12)]">
36
+ <div
37
+ className="inline-flex items-center gap-[var(--bh-space-md-8)] text-sm text-muted-foreground"
38
+ role="status"
39
+ >
40
+ <Spinner
41
+ className="text-current"
42
+ style={{ "--bh-spinner-size": "calc(var(--bh-space-2xl-14) + var(--bh-space-xs-4))" } as React.CSSProperties}
43
+ />
44
+ Loading
45
+ </div>
46
+ <div
47
+ className="inline-flex items-center gap-[var(--bh-space-md-8)] text-sm text-muted-foreground"
48
+ role="status"
49
+ >
50
+ <DynamicSpinner
51
+ className="text-current"
52
+ style={{ "--bh-spinner-size": "calc(var(--bh-space-2xl-14) + var(--bh-space-xs-4))" } as React.CSSProperties}
53
+ />
54
+ Syncing
55
+ </div>
56
+ </div>
57
+ </div>
58
+ )
59
+ }
@@ -0,0 +1,28 @@
1
+ import * as React from "react"
2
+
3
+ import { Button } from "@/components/ui/button"
4
+ import { StreamingText, useTypewriter } from "@/components/ui/streaming-text"
5
+
6
+ const response =
7
+ "The migration touches three files. I will add the sessions table first, wire the auth middleware next, and finish with the login flow so every step stays independently testable."
8
+
9
+ function TypedResponse({ text }: { text: string }) {
10
+ const typed = useTypewriter(text)
11
+ return <StreamingText streaming={typed.typing} text={typed.text} />
12
+ }
13
+
14
+ export function StreamingTextDemo() {
15
+ const [run, setRun] = React.useState(0)
16
+
17
+ return (
18
+ <div className="grid max-w-[var(--bh-space-19xl-384)] gap-[var(--bh-space-3xl-16)]">
19
+ <TypedResponse key={run} text={response} />
20
+
21
+ <div>
22
+ <Button onClick={() => setRun((value) => value + 1)} size="sm" variant="soft">
23
+ Replay
24
+ </Button>
25
+ </div>
26
+ </div>
27
+ )
28
+ }
@@ -1,13 +1,13 @@
1
- import { Tabs } from "@/components/ui/tabs"
2
-
3
- const tabItems = ["Overview", "Details", "Settings", "Activity", "Files"]
4
-
5
- export function TabsDemo() {
6
- return (
7
- <div className="grid gap-[var(--bh-space-5xl-24)]">
8
- <Tabs ariaLabel="Tabs" items={tabItems} />
9
- <Tabs ariaLabel="Tabs" items={tabItems} variant="segment" />
10
- <Tabs ariaLabel="Tabs" items={tabItems} variant="rounded" />
11
- </div>
12
- )
13
- }
1
+ import { Tabs } from "@/components/ui/tabs"
2
+
3
+ const tabItems = ["Overview", "Details", "Settings", "Activity", "Files"]
4
+
5
+ export function TabsDemo() {
6
+ return (
7
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
8
+ <Tabs ariaLabel="Tabs" items={tabItems} />
9
+ <Tabs ariaLabel="Tabs" items={tabItems} variant="segment" />
10
+ <Tabs ariaLabel="Tabs" items={tabItems} variant="rounded" />
11
+ </div>
12
+ )
13
+ }
@@ -1,29 +1,29 @@
1
- import { PlusIcon } from "lucide-react"
2
-
3
- import { Tag } from "@/components/ui/tag"
4
-
5
- export function TagDemo() {
6
- return (
7
- <div className="flex flex-wrap items-center gap-[var(--bh-space-md-8)]">
8
- <Tag>Label</Tag>
9
- <Tag state="active">Active</Tag>
10
- <Tag state="disabled">Disabled</Tag>
11
- <Tag closeLabel="Remove tag" showCloseButton>Label</Tag>
12
- <Tag closeLabel="Remove tag" type="dot" showCloseButton>
13
- Live
14
- </Tag>
15
- <Tag closeLabel="Remove tag" type="flag" showCloseButton>
16
- Egypt
17
- </Tag>
18
- <Tag closeLabel="Remove tag" type="avatar" avatar="AG" showCloseButton>
19
- Ahmed
20
- </Tag>
21
- <Tag closeLabel="Remove tag" type="icon" icon={<PlusIcon aria-hidden="true" />} showCloseButton>
22
- Add
23
- </Tag>
24
- <Tag closeLabel={"\u0625\u0632\u0627\u0644\u0629 \u0648\u0633\u0645"} dir="rtl" showCloseButton>
25
- ملصق
26
- </Tag>
27
- </div>
28
- )
29
- }
1
+ import { PlusIcon } from "lucide-react"
2
+
3
+ import { Tag } from "@/components/ui/tag"
4
+
5
+ export function TagDemo() {
6
+ return (
7
+ <div className="flex flex-wrap items-center gap-[var(--bh-space-md-8)]">
8
+ <Tag>Label</Tag>
9
+ <Tag state="active">Active</Tag>
10
+ <Tag state="disabled">Disabled</Tag>
11
+ <Tag closeLabel="Remove tag" showCloseButton>Label</Tag>
12
+ <Tag closeLabel="Remove tag" type="dot" showCloseButton>
13
+ Live
14
+ </Tag>
15
+ <Tag closeLabel="Remove tag" type="flag" showCloseButton>
16
+ Egypt
17
+ </Tag>
18
+ <Tag closeLabel="Remove tag" type="avatar" avatar="AG" showCloseButton>
19
+ Ahmed
20
+ </Tag>
21
+ <Tag closeLabel="Remove tag" type="icon" icon={<PlusIcon aria-hidden="true" />} showCloseButton>
22
+ Add
23
+ </Tag>
24
+ <Tag closeLabel={"\u0625\u0632\u0627\u0644\u0629 \u0648\u0633\u0645"} dir="rtl" showCloseButton>
25
+ ملصق
26
+ </Tag>
27
+ </div>
28
+ )
29
+ }
@@ -0,0 +1,74 @@
1
+ import * as React from "react"
2
+
3
+ import { Button } from "@/components/ui/button"
4
+ import { TaskList, type TaskListItem } from "@/components/ui/task-list"
5
+
6
+ const labels = [
7
+ "Scaffold the project structure",
8
+ "Build the component registry",
9
+ "Implement entitlement gating",
10
+ "Wire up Stripe checkout",
11
+ "Polish the landing page",
12
+ ]
13
+
14
+ const startDelay = 700
15
+ // How long each task stays active before completing.
16
+ const stepDuration = 2250
17
+
18
+ /**
19
+ * Walks the scripted tasks from pending to active to done. A real agent
20
+ * updates each item status as its work progresses.
21
+ */
22
+ function useScriptedTasks(run: number): TaskListItem[] {
23
+ // -1 = not started, 0..n-1 = index of the active task, n = all done.
24
+ const [current, setCurrent] = React.useState(-1)
25
+
26
+ React.useEffect(() => {
27
+ setCurrent(-1)
28
+
29
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
30
+ setCurrent(labels.length)
31
+ return
32
+ }
33
+
34
+ const timers = [window.setTimeout(() => setCurrent(0), startDelay)]
35
+ labels.forEach((_, index) => {
36
+ timers.push(
37
+ window.setTimeout(
38
+ () => setCurrent(index + 1),
39
+ startDelay + (index + 1) * stepDuration
40
+ )
41
+ )
42
+ })
43
+
44
+ return () => timers.forEach((timer) => window.clearTimeout(timer))
45
+ }, [run])
46
+
47
+ return labels.map((label, index) => ({
48
+ id: String(index),
49
+ label,
50
+ status:
51
+ current >= 0 && index < current
52
+ ? "done"
53
+ : index === current && current < labels.length
54
+ ? "active"
55
+ : "pending",
56
+ }))
57
+ }
58
+
59
+ export function TaskListDemo() {
60
+ const [run, setRun] = React.useState(0)
61
+ const items = useScriptedTasks(run)
62
+
63
+ return (
64
+ <div className="grid max-w-[var(--bh-space-18xl-320)] gap-[var(--bh-space-3xl-16)]">
65
+ <TaskList items={items} />
66
+
67
+ <div>
68
+ <Button onClick={() => setRun((value) => value + 1)} size="sm" variant="soft">
69
+ Replay
70
+ </Button>
71
+ </div>
72
+ </div>
73
+ )
74
+ }
@@ -1,79 +1,79 @@
1
- import { Textarea } from "@/components/ui/textarea"
2
-
3
- const demoTags = [{ label: "Label", removeLabel: "Remove tag" }]
4
- const demoRtlTags = [
5
- {
6
- label: "\u0645\u0644\u0635\u0642",
7
- removeLabel: "\u0625\u0632\u0627\u0644\u0629 \u0648\u0633\u0645",
8
- },
9
- ]
10
-
11
- const demoTextareaProps = {
12
- bodyText: "Our advanced inference infrastructure provides extremely short response.",
13
- errorMessage: "Error message",
14
- label: "Label",
15
- message: "This is a hint text",
16
- optionalText: "(Optional)",
17
- placeholder: "Type text here",
18
- tagInputText: "Brando...",
19
- }
20
-
21
- const demoRtlTextareaProps = {
22
- ...demoTextareaProps,
23
- bodyText:
24
- "\u062a\u0648\u0641\u0631 \u0628\u0646\u064a\u062a\u0646\u0627 \u0627\u0644\u062a\u062d\u062a\u064a\u0629 \u0627\u0644\u0645\u062a\u0642\u062f\u0645\u0629 \u0644\u0644\u0625\u0633\u062a\u062f\u0644\u0627\u0644 \u0623\u0648\u0642\u0627\u062a \u0627\u0633\u062a\u062c\u0627\u0628\u0629 \u0642\u0635\u064a\u0631\u0629 \u0644\u0644\u063a\u0627\u064a\u0629.",
25
- errorMessage: "\u0631\u0633\u0627\u0644\u0629 \u062e\u0637\u0623",
26
- label: "\u0645\u0644\u0635\u0642",
27
- message: "\u0646\u0635 \u062a\u0648\u0636\u064a\u062d\u064a",
28
- optionalText: "(\u062e\u064a\u0627\u0631\u064a)",
29
- tagInputText: "\u0628\u0631\u0627\u0646\u062f\u0648...",
30
- }
31
-
32
- export function TextareaDemo() {
33
- return (
34
- <div className="grid gap-[var(--bh-space-5xl-24)]">
35
- <div className="flex flex-wrap items-start gap-[var(--bh-space-5xl-24)]">
36
- <Textarea {...demoTextareaProps} />
37
- <Textarea {...demoTextareaProps} state="filled" />
38
- <Textarea {...demoTextareaProps} hasError state="placeholder" />
39
- <Textarea {...demoTextareaProps} state="disabled" />
40
- </div>
41
-
42
- <div className="flex flex-wrap items-start gap-[var(--bh-space-5xl-24)]">
43
- <Textarea {...demoTextareaProps} type="tags" state="placeholder" />
44
- <Textarea
45
- {...demoTextareaProps}
46
- type="tags"
47
- state="filled"
48
- tags={demoTags}
49
- />
50
- <Textarea
51
- {...demoTextareaProps}
52
- type="tags"
53
- hasError
54
- state="filled"
55
- tags={demoTags}
56
- />
57
- <Textarea
58
- {...demoTextareaProps}
59
- type="tags"
60
- state="disabled"
61
- tags={demoTags}
62
- />
63
- </div>
64
-
65
- <div dir="rtl" className="flex flex-wrap items-start gap-[var(--bh-space-5xl-24)]">
66
- <Textarea {...demoRtlTextareaProps} dir="rtl" />
67
- <Textarea {...demoRtlTextareaProps} dir="rtl" state="filled" />
68
- <Textarea {...demoRtlTextareaProps} dir="rtl" hasError state="placeholder" />
69
- <Textarea
70
- {...demoRtlTextareaProps}
71
- dir="rtl"
72
- type="tags"
73
- state="filled"
74
- tags={demoRtlTags}
75
- />
76
- </div>
77
- </div>
78
- )
79
- }
1
+ import { Textarea } from "@/components/ui/textarea"
2
+
3
+ const demoTags = [{ label: "Label", removeLabel: "Remove tag" }]
4
+ const demoRtlTags = [
5
+ {
6
+ label: "\u0645\u0644\u0635\u0642",
7
+ removeLabel: "\u0625\u0632\u0627\u0644\u0629 \u0648\u0633\u0645",
8
+ },
9
+ ]
10
+
11
+ const demoTextareaProps = {
12
+ bodyText: "Our advanced inference infrastructure provides extremely short response.",
13
+ errorMessage: "Error message",
14
+ label: "Label",
15
+ message: "This is a hint text",
16
+ optionalText: "(Optional)",
17
+ placeholder: "Type text here",
18
+ tagInputText: "Brando...",
19
+ }
20
+
21
+ const demoRtlTextareaProps = {
22
+ ...demoTextareaProps,
23
+ bodyText:
24
+ "\u062a\u0648\u0641\u0631 \u0628\u0646\u064a\u062a\u0646\u0627 \u0627\u0644\u062a\u062d\u062a\u064a\u0629 \u0627\u0644\u0645\u062a\u0642\u062f\u0645\u0629 \u0644\u0644\u0625\u0633\u062a\u062f\u0644\u0627\u0644 \u0623\u0648\u0642\u0627\u062a \u0627\u0633\u062a\u062c\u0627\u0628\u0629 \u0642\u0635\u064a\u0631\u0629 \u0644\u0644\u063a\u0627\u064a\u0629.",
25
+ errorMessage: "\u0631\u0633\u0627\u0644\u0629 \u062e\u0637\u0623",
26
+ label: "\u0645\u0644\u0635\u0642",
27
+ message: "\u0646\u0635 \u062a\u0648\u0636\u064a\u062d\u064a",
28
+ optionalText: "(\u062e\u064a\u0627\u0631\u064a)",
29
+ tagInputText: "\u0628\u0631\u0627\u0646\u062f\u0648...",
30
+ }
31
+
32
+ export function TextareaDemo() {
33
+ return (
34
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
35
+ <div className="flex flex-wrap items-start gap-[var(--bh-space-5xl-24)]">
36
+ <Textarea {...demoTextareaProps} />
37
+ <Textarea {...demoTextareaProps} state="filled" />
38
+ <Textarea {...demoTextareaProps} hasError state="placeholder" />
39
+ <Textarea {...demoTextareaProps} state="disabled" />
40
+ </div>
41
+
42
+ <div className="flex flex-wrap items-start gap-[var(--bh-space-5xl-24)]">
43
+ <Textarea {...demoTextareaProps} type="tags" state="placeholder" />
44
+ <Textarea
45
+ {...demoTextareaProps}
46
+ type="tags"
47
+ state="filled"
48
+ tags={demoTags}
49
+ />
50
+ <Textarea
51
+ {...demoTextareaProps}
52
+ type="tags"
53
+ hasError
54
+ state="filled"
55
+ tags={demoTags}
56
+ />
57
+ <Textarea
58
+ {...demoTextareaProps}
59
+ type="tags"
60
+ state="disabled"
61
+ tags={demoTags}
62
+ />
63
+ </div>
64
+
65
+ <div dir="rtl" className="flex flex-wrap items-start gap-[var(--bh-space-5xl-24)]">
66
+ <Textarea {...demoRtlTextareaProps} dir="rtl" />
67
+ <Textarea {...demoRtlTextareaProps} dir="rtl" state="filled" />
68
+ <Textarea {...demoRtlTextareaProps} dir="rtl" hasError state="placeholder" />
69
+ <Textarea
70
+ {...demoRtlTextareaProps}
71
+ dir="rtl"
72
+ type="tags"
73
+ state="filled"
74
+ tags={demoRtlTags}
75
+ />
76
+ </div>
77
+ </div>
78
+ )
79
+ }
@@ -0,0 +1,74 @@
1
+ import * as React from "react"
2
+
3
+ import { Button } from "@/components/ui/button"
4
+ import { ThinkingReasoning } from "@/components/ui/thinking-reasoning"
5
+
6
+ const reasoning = [
7
+ "Reading the request and the current selection, then locating the jwt.verify call inside the auth middleware.",
8
+ "The verify call sets no algorithms allowlist, so a token signed with none or a weak cipher could be accepted.",
9
+ "Tracing where the signing secret is loaded from and confirming it is never logged or sent back to the client.",
10
+ "Planning to pin the algorithm to HS256 and to validate the issuer and audience claims on every incoming request.",
11
+ "Scanning the existing tests around the middleware so the fix stays covered and nothing downstream regresses.",
12
+ "Drafting the patch with a focused regression test that rejects tampered, expired, and unsigned tokens.",
13
+ ]
14
+
15
+ // Per-sentence arrival cadence in milliseconds; sums to roughly five seconds.
16
+ const delays = [700, 900, 800, 850, 800, 900]
17
+ const collapseBeat = 360
18
+
19
+ /**
20
+ * Replays a scripted reasoning stream. A real integration appends each
21
+ * sentence as it arrives and flips the status to done when the model stops.
22
+ */
23
+ function useScriptedReasoning(run: number) {
24
+ const [revealed, setRevealed] = React.useState(0)
25
+ const [status, setStatus] = React.useState<"thinking" | "done">("thinking")
26
+
27
+ React.useEffect(() => {
28
+ setRevealed(0)
29
+ setStatus("thinking")
30
+
31
+ if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) {
32
+ setRevealed(reasoning.length)
33
+ setStatus("done")
34
+ return
35
+ }
36
+
37
+ const timers: number[] = []
38
+ let elapsed = 0
39
+ delays.forEach((delay, index) => {
40
+ elapsed += delay
41
+ timers.push(window.setTimeout(() => setRevealed(index + 1), elapsed))
42
+ })
43
+ timers.push(
44
+ window.setTimeout(() => setStatus("done"), elapsed + collapseBeat)
45
+ )
46
+
47
+ return () => timers.forEach((timer) => window.clearTimeout(timer))
48
+ }, [run])
49
+
50
+ return { status, steps: reasoning.slice(0, revealed) }
51
+ }
52
+
53
+ export function ThinkingReasoningDemo() {
54
+ const [run, setRun] = React.useState(0)
55
+ const { status, steps } = useScriptedReasoning(run)
56
+
57
+ return (
58
+ <div className="grid gap-[var(--bh-space-3xl-16)]">
59
+ <ThinkingReasoning
60
+ duration={5}
61
+ key={run}
62
+ reserveSpace
63
+ status={status}
64
+ steps={steps}
65
+ />
66
+
67
+ <div>
68
+ <Button onClick={() => setRun((value) => value + 1)} size="sm" variant="soft">
69
+ Replay
70
+ </Button>
71
+ </div>
72
+ </div>
73
+ )
74
+ }
@@ -0,0 +1,13 @@
1
+ import { ThinkingState } from "@/components/ui/thinking-state"
2
+
3
+ export function ThinkingStateDemo() {
4
+ return (
5
+ <div className="grid gap-[var(--bh-space-3xl-16)]">
6
+ <ThinkingState />
7
+
8
+ <div dir="rtl">
9
+ <ThinkingState>جارٍ التفكير</ThinkingState>
10
+ </div>
11
+ </div>
12
+ )
13
+ }
@@ -1,35 +1,35 @@
1
- import { Button } from "@/components/ui/button"
2
- import { Toaster, toast } from "@/components/ui/toast"
3
-
4
- export function ToastDemo() {
5
- return (
6
- <div className="grid gap-[var(--bh-space-3xl-16)]">
7
- <div className="flex flex-wrap gap-[var(--bh-space-md-8)]">
8
- <Button size="sm" onClick={() => toast.success("Project saved")}>
9
- Success
10
- </Button>
11
- <Button size="sm" variant="warning" onClick={() => toast.warning("Review required")}>
12
- Warning
13
- </Button>
14
- <Button size="sm" variant="danger" onClick={() => toast.danger("Unable to publish")}>
15
- Danger
16
- </Button>
17
- <Button
18
- size="sm"
19
- variant="outline"
20
- onClick={() =>
21
- toast.info("Invite sent", {
22
- action: {
23
- label: "Undo",
24
- onClick: () => toast("Invite cancelled"),
25
- },
26
- })
27
- }
28
- >
29
- Action
30
- </Button>
31
- </div>
32
- <Toaster />
33
- </div>
34
- )
35
- }
1
+ import { Button } from "@/components/ui/button"
2
+ import { Toaster, toast } from "@/components/ui/toast"
3
+
4
+ export function ToastDemo() {
5
+ return (
6
+ <div className="grid gap-[var(--bh-space-3xl-16)]">
7
+ <div className="flex flex-wrap gap-[var(--bh-space-md-8)]">
8
+ <Button size="sm" onClick={() => toast.success("Project saved")}>
9
+ Success
10
+ </Button>
11
+ <Button size="sm" variant="warning" onClick={() => toast.warning("Review required")}>
12
+ Warning
13
+ </Button>
14
+ <Button size="sm" variant="danger" onClick={() => toast.danger("Unable to publish")}>
15
+ Danger
16
+ </Button>
17
+ <Button
18
+ size="sm"
19
+ variant="outline"
20
+ onClick={() =>
21
+ toast.info("Invite sent", {
22
+ action: {
23
+ label: "Undo",
24
+ onClick: () => toast("Invite cancelled"),
25
+ },
26
+ })
27
+ }
28
+ >
29
+ Action
30
+ </Button>
31
+ </div>
32
+ <Toaster />
33
+ </div>
34
+ )
35
+ }