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,56 +1,60 @@
1
- # Tabs
2
-
3
- Tabs is a Radix-backed local navigation primitive with underline, segmented, and rounded treatments across size, full-width behavior, controlled state, LTR, and RTL.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <Tabs
9
- ariaLabel="Project sections"
10
- items={["Overview", "Activity", "Settings"]}
11
- variant="underline"
12
- />
13
- ```
14
-
15
- | Prop | Values |
16
- | --- | --- |
17
- | `variant` | `underline`, `segment`, `rounded` |
18
- | `size` | `md`, `sm`, `xs` |
19
- | `fullWidth` | `boolean` |
20
- | `activeIndex`, `defaultActiveIndex` | controlled or uncontrolled index |
21
- | `onActiveIndexChange` | selected-index callback |
22
-
23
- ## Token Contract
24
-
25
- Tabs uses Banhaten tab CSS variables for sizes, spacing, border, radius, active indicators, surfaces, and content states.
26
-
27
- ## RTL
28
-
29
- Tabs accepts `dir="rtl"` and mirrors layout through inherited direction. Labels should remain short enough for each treatment and viewport.
30
-
31
- ## Accessibility
32
-
33
- Tabs uses Radix Tabs so keyboard behavior, roving focus, activation mode, trigger state, and panel relationships come from the primitive.
34
-
35
- ## Install
36
-
37
- ```bash
38
- npx banhaten add tabs
39
- ```
40
-
41
- ## Examples
42
-
43
- Primary registry example: `examples/tabs-demo.tsx`.
44
-
45
- Open the live component page or run `npx banhaten docs tabs` to inspect source files, install command, and examples.
46
-
47
- ## RTL Rules
48
-
49
- - `inheritsDirection`: true
50
- - `keyboard`: Radix receives dir so arrow-key navigation follows the document direction.
51
- - `textDirection`: Trigger labels use dir="auto" by default for Arabic and English tab labels.
52
- - `spacing`: Uses inherited direction and logical inline spacing so underline, segmented, and rounded treatments mirror naturally.
53
-
1
+ # Tabs
2
+
3
+ Tabs is a Radix-backed local navigation primitive with underline, segmented, and rounded treatments across size, full-width behavior, controlled state, LTR, and RTL.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <Tabs
9
+ ariaLabel="Project sections"
10
+ items={["Overview", "Activity", "Settings"]}
11
+ variant="underline"
12
+ />
13
+ ```
14
+
15
+ | Prop | Values |
16
+ | --- | --- |
17
+ | `variant` | `underline`, `segment`, `rounded` |
18
+ | `size` | `md`, `sm`, `xs` |
19
+ | `fullWidth` | `boolean`; default `false`. Equal shares while labels fit; content-safe scrolling under pressure. |
20
+ | `activeIndex`, `defaultActiveIndex` | controlled or uncontrolled index |
21
+ | `onActiveIndexChange` | selected-index callback |
22
+
23
+ ## Token Contract
24
+
25
+ Tabs uses Banhaten tab CSS variables for sizes, spacing, border, radius, active indicators, surfaces, and content states.
26
+
27
+ ## RTL
28
+
29
+ Tabs accepts `dir="rtl"` and mirrors layout through inherited direction. Trigger labels stay complete in both directions: content-hug tabs keep their intrinsic width, while full-width tabs keep equal shares until a label's intrinsic width requires horizontal overflow.
30
+
31
+ ## Overflow
32
+
33
+ Tab labels stay on one line and are never painted outside their trigger. When all triggers cannot fit, the tab list owns horizontal scrolling. `fullWidth` changes how spare inline space is distributed; it does not enable truncation or unsafe shrinking.
34
+
35
+ ## Accessibility
36
+
37
+ Tabs uses Radix Tabs so keyboard behavior, roving focus, activation mode, trigger state, and panel relationships come from the primitive.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ npx banhaten add tabs
43
+ ```
44
+
45
+ ## Examples
46
+
47
+ Primary registry example: `examples/tabs-demo.tsx`.
48
+
49
+ Open the live component page or run `npx banhaten docs tabs` to inspect source files, install command, and examples.
50
+
51
+ ## RTL Rules
52
+
53
+ - `inheritsDirection`: true
54
+ - `keyboard`: Radix receives dir so arrow-key navigation follows the document direction.
55
+ - `textDirection`: Trigger labels use dir="auto" by default for Arabic and English tab labels.
56
+ - `spacing`: Uses inherited direction and logical inline spacing so underline, segmented, and rounded treatments mirror naturally.
57
+
54
58
  <!-- registry-contract:start -->
55
59
  ## Registry Contract
56
60
 
@@ -62,8 +66,8 @@ This table is generated from `registry/index.json`; edit the component-owned sou
62
66
  | `supportedExports` | `components/tabs.tsx: Tabs, TabsContent, TabsList, TabsRoot, TabsTrigger` |
63
67
  | `parts` | `Tabs`, `TabsRoot`, `TabsList`, `TabsTrigger`, `TabsContent` |
64
68
  | `registryDependencies` | None |
65
- | `features` | `Radix keyboard behavior`, `controlled active index`, `controlled value`, `optional panels`, `full-width tabs` |
69
+ | `features` | `Radix keyboard behavior`, `controlled active index`, `controlled value`, `optional panels`, `content-hug tabs`, `content-safe full-width tabs`, `horizontal overflow without label overlap` |
66
70
  | `sizes` | `md`, `sm`, `xs` |
67
- | `tokens` | `--bh-bg-default`, `--bh-bg-neutral-subtle`, `--bh-border-default`, `--bh-content-brand-default`, `--bh-content-default`, `--bh-content-subtle`, `--bh-font-family`, `--bh-font-weight-medium`, `--bh-opacity-60`, `--bh-radius-full`, `--bh-radius-lg-8`, `--bh-radius-md-6`, `--bh-space-3xl-16`, `--bh-space-6xl-32`, `--bh-space-7xl-40`, `--bh-space-8xl-48`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--bh-space-xxxs-1`, `--bh-text-body-md-regular-font-size`, `--bh-text-body-md-regular-font-weight`, `--bh-text-body-md-regular-letter-spacing`, `--bh-text-body-md-regular-line-height`, `--shadow-button-soft` |
71
+ | `tokens` | `--bh-bg-default`, `--bh-bg-neutral-subtle`, `--bh-border-default`, `--bh-content-brand-default`, `--bh-content-default`, `--bh-content-subtle`, `--bh-font-family`, `--bh-font-weight-medium`, `--bh-opacity-60`, `--bh-radius-full`, `--bh-radius-lg-8`, `--bh-radius-md-6`, `--bh-space-3xl-16`, `--bh-space-6xl-32`, `--bh-space-7xl-40`, `--bh-space-8xl-48`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--bh-space-xxxs-1`, `--bh-text-body-md-regular-font-size`, `--bh-text-body-md-regular-font-weight`, `--bh-text-body-md-regular-letter-spacing`, `--bh-text-body-md-regular-line-height`, `--elevation-button-soft` |
68
72
  | `variants` | `underline`, `segment`, `rounded` |
69
73
  <!-- registry-contract:end -->
@@ -1,82 +1,82 @@
1
- # Tag
2
-
3
- Tags identify compact metadata, filters, or removable selections.
4
-
5
- The implementation follows the Figma component at `Design system 3.0 Copy / Tag` (`188:64712`). It supports every variant in the matrix: `simple`, `dot`, `flag`, `avatar`, and `icon`; `default`, `active`, and `disabled` states with native hover and focus-visible styling; `xs`, `md`, and `lg` sizes; optional close button; LTR and RTL.
6
-
7
- ## API
8
-
9
- ```tsx
10
- <Tag
11
- type="simple"
12
- size="md"
13
- state="default"
14
- showCloseButton={false}
15
- dir="ltr"
16
- >
17
- Label
18
- </Tag>
19
- ```
20
-
21
- | Prop | Values | Default |
22
- | --- | --- | --- |
23
- | `type` | `simple`, `dot`, `flag`, `avatar`, `icon` | `simple` |
24
- | `size` | `xs`, `md`, `lg` | `md` |
25
- | `state` | `default`, `active`, `disabled` | `default` |
26
- | `showCloseButton` | `boolean` | `false` |
27
- | `disabled` | `boolean` | `false` |
28
- | `dir` | `ltr`, `rtl`, `auto` | `auto` |
29
- | `avatar` | `ReactNode` | initials placeholder |
30
- | `flag` | `ReactNode` | token-colored placeholder |
31
- | `icon` | `ReactNode` | plus icon |
32
- | `onClose` | close-button click handler | none |
33
-
34
- ## Token Contract
35
-
36
- The component consumes semantic design-system tokens only:
37
-
38
- - Text and icons: `content.default`, `content.disabled`, `content.primary`, `content.onColor`, `content.muted`
39
- - Backgrounds: `background.default`, `background.hover`, `background.pressed`, `background.disabled`, `background.selected`, `background.danger`
40
- - Borders: `border.default`, `border.disabled`, `border.brand`, `border.focus`, `border.subtle`
41
- - Shape: `shape.control`, `shape.badge`, `shape.avatar`
42
- - Density: `density.controlHeight`, `density.controlPaddingX`
43
-
44
- ## Pixel Rules
45
-
46
- - `xs` tags are `24px` tall and use body-xs medium text.
47
- - `md` tags are `28px` tall and use body-sm medium text.
48
- - `lg` tags are `36px` tall and use body-md medium text.
49
- - Simple tags use centered text and no leading slot.
50
- - Dot, flag, avatar, and icon tags use a `20px` leading slot.
51
- - Close buttons are `16px` with a `12px` icon.
52
- - Focused tags use a brand border plus an outside focus ring at reduced opacity.
53
- - Active tags use selected/brand treatment and a stronger brand border.
54
- - Disabled tags use disabled background, border, and content tokens.
55
- - RTL uses logical inline padding and inherited direction so leading media, label, and close button mirror naturally.
56
-
57
- ## Install
58
-
59
- ```bash
60
- npx banhaten add tag
61
- ```
62
-
63
- ## Examples
64
-
65
- Primary registry example: `examples/tag-demo.tsx`.
66
-
67
- Open the live component page or run `npx banhaten docs tag` to inspect source files, install command, and examples.
68
-
69
- ## RTL Rules
70
-
71
- - `inheritsDirection`: true
72
- - `spacing`: Uses logical inline padding and inherited flex direction so the leading media, label, and close button mirror naturally.
73
- - `textDirection`: Text labels use dir="auto" for short Arabic and English tag labels.
74
- - `closeButton`: The close affordance is a 16px token-sized icon button using currentColor and the tag disabled state.
75
-
76
- ## Accessibility
77
-
78
- This component relies on `@radix-ui/react-slot` for its base accessibility behavior. Keep required labels, titles, descriptions, and focusable trigger/content relationships intact when composing it.
79
-
1
+ # Tag
2
+
3
+ Tags identify compact metadata, filters, or removable selections.
4
+
5
+ The implementation follows the Figma component at `Design system 3.0 Copy / Tag` (`188:64712`). It supports every variant in the matrix: `simple`, `dot`, `flag`, `avatar`, and `icon`; `default`, `active`, and `disabled` states with native hover and focus-visible styling; `xs`, `md`, and `lg` sizes; optional close button; LTR and RTL.
6
+
7
+ ## API
8
+
9
+ ```tsx
10
+ <Tag
11
+ type="simple"
12
+ size="md"
13
+ state="default"
14
+ showCloseButton={false}
15
+ dir="ltr"
16
+ >
17
+ Label
18
+ </Tag>
19
+ ```
20
+
21
+ | Prop | Values | Default |
22
+ | --- | --- | --- |
23
+ | `type` | `simple`, `dot`, `flag`, `avatar`, `icon` | `simple` |
24
+ | `size` | `xs`, `md`, `lg` | `md` |
25
+ | `state` | `default`, `active`, `disabled` | `default` |
26
+ | `showCloseButton` | `boolean` | `false` |
27
+ | `disabled` | `boolean` | `false` |
28
+ | `dir` | `ltr`, `rtl`, `auto` | `auto` |
29
+ | `avatar` | `ReactNode` | initials placeholder |
30
+ | `flag` | `ReactNode` | token-colored placeholder |
31
+ | `icon` | `ReactNode` | plus icon |
32
+ | `onClose` | close-button click handler | none |
33
+
34
+ ## Token Contract
35
+
36
+ The component consumes semantic design-system tokens only:
37
+
38
+ - Text and icons: `content.default`, `content.disabled`, `content.primary`, `content.onColor`, `content.muted`
39
+ - Backgrounds: `background.default`, `background.hover`, `background.pressed`, `background.disabled`, `background.selected`, `background.danger`
40
+ - Borders: `border.default`, `border.disabled`, `border.brand`, `border.focus`, `border.subtle`
41
+ - Shape: `shape.control`, `shape.badge`, `shape.avatar`
42
+ - Density: `density.controlHeight`, `density.controlPaddingX`
43
+
44
+ ## Pixel Rules
45
+
46
+ - `xs` tags are `24px` tall and use body-xs medium text.
47
+ - `md` tags are `28px` tall and use body-sm medium text.
48
+ - `lg` tags are `36px` tall and use body-md medium text.
49
+ - Simple tags use centered text and no leading slot.
50
+ - Dot, flag, avatar, and icon tags use a `20px` leading slot; the default icon glyph is `18px`.
51
+ - Close buttons are `16px` with a `12px` icon.
52
+ - Focused tags use a brand border plus a solid outside focus ring.
53
+ - Active tags use selected/brand treatment and a stronger brand border.
54
+ - Disabled tags use disabled background, border, and content tokens.
55
+ - RTL uses logical inline padding and inherited direction so leading media, label, and close button mirror naturally.
56
+
57
+ ## Install
58
+
59
+ ```bash
60
+ npx banhaten add tag
61
+ ```
62
+
63
+ ## Examples
64
+
65
+ Primary registry example: `examples/tag-demo.tsx`.
66
+
67
+ Open the live component page or run `npx banhaten docs tag` to inspect source files, install command, and examples.
68
+
69
+ ## RTL Rules
70
+
71
+ - `inheritsDirection`: true
72
+ - `spacing`: Uses logical inline padding and inherited flex direction so the leading media, label, and close button mirror naturally.
73
+ - `textDirection`: Text labels use dir="auto" for short Arabic and English tag labels.
74
+ - `closeButton`: The close affordance is a 16px token-sized icon button using currentColor and the tag disabled state.
75
+
76
+ ## Accessibility
77
+
78
+ This component relies on `@radix-ui/react-slot` for its base accessibility behavior. Keep required labels, titles, descriptions, and focusable trigger/content relationships intact when composing it.
79
+
80
80
  <!-- registry-contract:start -->
81
81
  ## Registry Contract
82
82
 
@@ -90,6 +90,6 @@ This table is generated from `registry/index.json`; edit the component-owned sou
90
90
  | `registryDependencies` | None |
91
91
  | `sizes` | `xs`, `md`, `lg` |
92
92
  | `states` | `default`, `active`, `disabled` |
93
- | `tokens` | `--bh-bg-accent-green-default`, `--bh-bg-always-dark`, `--bh-bg-always-white`, `--bh-bg-brand-subtle`, `--bh-bg-danger-default`, `--bh-bg-neutral-bold`, `--bh-bg-neutral-subtle`, `--bh-border-brand-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-focus`, `--bh-border-subtle`, `--bh-content-brand-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-on-neutral`, `--bh-control-default`, `--bh-control-md`, `--bh-icon-stroke-200`, `--bh-icon-stroke-225`, `--bh-interactive-ghost-hover`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-interactive-secondary-hover`, `--bh-opacity-30`, `--bh-radius-full`, `--bh-radius-xs-2`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-none`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-tag-active-border-width`, `--bh-tag-focus-ring-inset`, `--bh-tag-focus-ring-width`, `--bh-text-body-3xs-semibold-font-size`, `--bh-text-body-3xs-semibold-font-weight`, `--bh-text-body-3xs-semibold-line-height`, `--bh-text-body-md-medium-font-size`, `--bh-text-body-md-medium-font-weight`, `--bh-text-body-md-medium-letter-spacing`, `--bh-text-body-md-medium-line-height`, `--bh-text-body-sm-medium-font-size`, `--bh-text-body-sm-medium-font-weight`, `--bh-text-body-sm-medium-letter-spacing`, `--bh-text-body-sm-medium-line-height`, `--bh-text-body-xs-medium-font-size`, `--bh-text-body-xs-medium-font-weight`, `--bh-text-body-xs-medium-letter-spacing`, `--bh-text-body-xs-medium-line-height`, `--bh-z-raised`, `--shadow-button-focus` |
93
+ | `tokens` | `--bh-bg-accent-green-default`, `--bh-bg-always-dark`, `--bh-bg-always-white`, `--bh-bg-brand-subtle`, `--bh-bg-danger-default`, `--bh-bg-neutral-bold`, `--bh-bg-neutral-subtle`, `--bh-border-brand-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-focus`, `--bh-border-subtle`, `--bh-content-brand-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-on-neutral`, `--bh-control-default`, `--bh-control-md`, `--bh-icon-size-default`, `--bh-icon-slot-size-default`, `--bh-icon-stroke-200`, `--bh-icon-stroke-225`, `--bh-interactive-ghost-hover`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-interactive-secondary-hover`, `--bh-opacity-30`, `--bh-radius-full`, `--bh-radius-xs-2`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-none`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-tag-active-border-width`, `--bh-tag-focus-ring-inset`, `--bh-tag-focus-ring-width`, `--bh-text-body-3xs-semibold-font-size`, `--bh-text-body-3xs-semibold-font-weight`, `--bh-text-body-3xs-semibold-line-height`, `--bh-text-body-md-medium-font-size`, `--bh-text-body-md-medium-font-weight`, `--bh-text-body-md-medium-letter-spacing`, `--bh-text-body-md-medium-line-height`, `--bh-text-body-sm-medium-font-size`, `--bh-text-body-sm-medium-font-weight`, `--bh-text-body-sm-medium-letter-spacing`, `--bh-text-body-sm-medium-line-height`, `--bh-text-body-xs-medium-font-size`, `--bh-text-body-xs-medium-font-weight`, `--bh-text-body-xs-medium-letter-spacing`, `--bh-text-body-xs-medium-line-height`, `--bh-z-raised`, `--elevation-button-focus` |
94
94
  | `types` | `simple`, `dot`, `flag`, `avatar`, `icon` |
95
95
  <!-- registry-contract:end -->
@@ -0,0 +1,95 @@
1
+ # Task List
2
+
3
+ `TaskList` is an agent progress tracker. Rows move from a dashed pending circle to an arrow while active (with a shimmering label) to a check when done. The header icon crossfades from a list to a determinate pie to a filled check, and the counter rolls its digits as work completes through [Rolling Count](./rolling-count.md).
4
+
5
+ For any other list, compose the parts instead of configuring the tracker: `TaskListRoot` draws the surface, `TaskListHeader` is a static header, `TaskListItems` renders rows, and `TaskListPreview` shows the first rows and folds the rest. [Approval Card](./approval-card.md) builds its plan this way.
6
+
7
+ ## API
8
+
9
+ ```tsx
10
+ import {
11
+ TaskList,
12
+ TaskListHeader,
13
+ TaskListPreview,
14
+ TaskListRoot,
15
+ type TaskListItem,
16
+ } from "@/components/ui/task-list"
17
+
18
+ const items: TaskListItem[] = [
19
+ { id: "1", label: "Scaffold the project structure", status: "done" },
20
+ { id: "2", label: "Build the component registry", status: "active" },
21
+ { id: "3", label: "Wire up checkout", status: "pending" },
22
+ ]
23
+
24
+ <TaskList items={items} />
25
+
26
+ <TaskListRoot surface="well">
27
+ <TaskListHeader count={items.length}>To-dos</TaskListHeader>
28
+ <TaskListPreview items={items} visibleCount={2} />
29
+ </TaskListRoot>
30
+ ```
31
+
32
+ ### TaskList
33
+
34
+ | Prop | Type | Default | Description |
35
+ | --- | --- | --- | --- |
36
+ | `items` | `readonly TaskListItem[]` | – | Rows with `id`, `label`, and `pending`, `active`, or `done` status. |
37
+ | `title` | `React.ReactNode` | `"To-dos"` | Header label. |
38
+ | `surface` | `"card" \| "well" \| "plain"` | `"card"` | Raised card, subtle well for embedding, or no surface. |
39
+ | `open` / `defaultOpen` / `onOpenChange` | `boolean` | `true` | Fold state. |
40
+ | `labels` | `Partial<TaskListLabels>` | English | `count(done, total)` copy, which the toggle reads after its title. |
41
+
42
+ ### Parts
43
+
44
+ | Part | Props | Description |
45
+ | --- | --- | --- |
46
+ | `TaskListRoot` | `surface` | Surface of a composed list. A header inside it names the rows. |
47
+ | `TaskListHeader` | `children`, `count`, `items` | Static header. `items` drives the icon from list to progress pie to check; `count` renders at the end. |
48
+ | `TaskListItems` | `items` | Rows. They start flush when no header sits above them. |
49
+ | `TaskListPreview` | `items`, `visibleCount` (`3`), `labels` | The first rows, then a Collapsible fold for the rest with `more(count)` and `less` copy. |
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ npx banhaten add task-list
55
+ ```
56
+
57
+ ## Examples
58
+
59
+ Primary registry example: `examples/task-list-demo.tsx`.
60
+
61
+ ## Token Contract
62
+
63
+ Surfaces use `--bh-bg-raised` with `--elevation-02` and `--bh-radius-2xl-12` (card) or `--bh-bg-subtle` with `--bh-radius-lg-8` (well). Rows use the `body-xs` scale, `--bh-task-list-icon-size` icons, `--bh-content-subtle` for muted rows, `--bh-content-default` for the active row, and `--bh-content-success-default` for the finished check. Motion uses the `--bh-duration-*` foundation tokens, rows enter `--bh-task-list-stagger` apart, and the active row uses the shared shimmer.
64
+
65
+ Covered source files: `components/task-list.tsx`, `components/task-list.css`, and the `collapsible`, `rolling-count`, and `shimmer-text` registry dependencies.
66
+
67
+ ## RTL Rules
68
+
69
+ - Rows, counters, and the collapse chevron use logical placement.
70
+ - The active arrow icon mirrors horizontally in RTL; the check and dashed circle are symmetric.
71
+
72
+ ## Accessibility
73
+
74
+ The collapsible header and the "more" control are Collapsible triggers with `aria-expanded` and `aria-controls`, named by what they show: the header by its title and progress, for example "To-dos 2 of 5 done". Folded rows unmount after their closing animation, so nothing hidden can be focused. Rows are labelled by the header title of their list, including a `TaskListHeader` composed inside `TaskListRoot`. Status changes are expressed through icons plus strikethrough, never color alone, and the counter carries an accessible "done of total" summary. Rolling digits, crossfades, and shimmer collapse to instant changes under `prefers-reduced-motion`.
75
+
76
+ <!-- registry-contract:start -->
77
+ ## Registry Contract
78
+
79
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
80
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
81
+
82
+ | Field | Values |
83
+ | --- | --- |
84
+ | `supportedExports` | `components/task-list.tsx: TaskList, TaskListHeader, TaskListItems, TaskListPreview, TaskListRoot` |
85
+ | `parts` | `TaskList`, `TaskListRoot`, `TaskListHeader`, `TaskListItems`, `TaskListPreview` |
86
+ | `registryDependencies` | `collapsible`, `rolling-count`, `shimmer-text` |
87
+ | `props.items` | `readonly TaskListItem[]; default null; Rows with id, label, and pending, active, or done status.` |
88
+ | `props.surface` | `"card" \| "well" \| "plain"; default "card"; Raised card, subtle well for embedding, or no surface.` |
89
+ | `props.labels` | `Partial<TaskListLabels>; default "English"; Localized counter copy, read after the title in the toggle's name.` |
90
+ | `props.visibleCount` | `number; default "3"; TaskListPreview: rows shown before the rest fold behind a more control.` |
91
+ | `features` | `controlled state`, `uncontrolled state`, `composable parts`, `preview fold`, `reduced motion`, `RTL` |
92
+ | `states` | `pending`, `active`, `done` |
93
+ | `tokens` | `--bh-bg-raised`, `--bh-bg-subtle`, `--bh-content-default`, `--bh-content-subtle`, `--bh-content-success-default`, `--bh-duration-default`, `--bh-duration-fast`, `--bh-duration-moderate`, `--bh-duration-slow`, `--bh-easing-standard`, `--bh-font-family`, `--bh-icon-stroke-180`, `--bh-icon-stroke-200`, `--bh-opacity-0`, `--bh-opacity-100`, `--bh-radius-2xl-12`, `--bh-radius-full`, `--bh-radius-lg-8`, `--bh-radius-sm-4`, `--bh-space-4xl-20`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--bh-space-xxxs-1`, `--bh-task-list-icon-size`, `--bh-task-list-stagger`, `--bh-text-body-xs-medium-font-weight`, `--bh-text-body-xs-regular-font-size`, `--bh-text-body-xs-regular-font-weight`, `--bh-text-body-xs-regular-letter-spacing`, `--bh-text-body-xs-regular-line-height`, `--elevation-02`, `--elevation-component-focus-ring` |
94
+ | `variants` | `card`, `well`, `plain` |
95
+ <!-- registry-contract:end -->
@@ -1,52 +1,52 @@
1
- # Textarea
2
-
3
- Textarea is the multiline field primitive for comments, notes, descriptions, and tag-style text entry. It supports label, helper and error text, default and tags modes, placeholder, filled, disabled, and RTL states.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <Textarea label="Comments" placeholder="Add context..." />
9
- <Textarea mode="tags" label="Tags" defaultValue="Design, System" />
10
- ```
11
-
12
- | Prop | Values |
13
- | --- | --- |
14
- | `mode` | `default`, `tags` |
15
- | `state` | `placeholder`, `filled`, `disabled` |
16
- | `hasError` | `boolean` |
17
- | `label`, `helperText` | `ReactNode` |
18
- | `dir` | `ltr`, `rtl` |
19
-
20
- ## Token Contract
21
-
22
- Textarea uses Banhaten field surface, text, label, helper, error, tag, spacing, border, radius, disabled, and focus tokens.
23
-
24
- ## RTL
25
-
26
- Textarea uses `text-start`, inherited direction, and logical field layout. Labels, helper text, and tag chips mirror without physical left/right styling.
27
-
28
- ## Accessibility
29
-
30
- Connect labels and helper/error text through component props. Use visible error text with `hasError` rather than color alone.
31
-
32
- ## Install
33
-
34
- ```bash
35
- npx banhaten add textarea
36
- ```
37
-
38
- ## Examples
39
-
40
- Primary registry example: `examples/textarea-demo.tsx`.
41
-
42
- Open the live component page or run `npx banhaten docs textarea` to inspect source files, install command, and examples.
43
-
44
- ## RTL Rules
45
-
46
- - `inheritsDirection`: true
47
- - `textAlignment`: Uses text-start and dir="auto" so Arabic and English content align naturally.
48
- - `spacing`: Uses inherited direction and flex order so labels, helper icons, and tag chips mirror without physical left/right rules.
49
-
1
+ # Textarea
2
+
3
+ Textarea is the multiline field primitive for comments, notes, descriptions, and tag-style text entry. It supports label, helper and error text, default and tags modes, placeholder, filled, disabled, and RTL states.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <Textarea label="Comments" placeholder="Add context..." />
9
+ <Textarea mode="tags" label="Tags" defaultValue="Design, System" />
10
+ ```
11
+
12
+ | Prop | Values |
13
+ | --- | --- |
14
+ | `mode` | `default`, `tags` |
15
+ | `state` | `placeholder`, `filled`, `disabled` |
16
+ | `hasError` | `boolean` |
17
+ | `label`, `helperText` | `ReactNode` |
18
+ | `dir` | `ltr`, `rtl` |
19
+
20
+ ## Token Contract
21
+
22
+ Textarea uses Banhaten field surface, text, label, helper, error, tag, spacing, border, radius, disabled, and focus tokens.
23
+
24
+ ## RTL
25
+
26
+ Textarea uses `text-start`, inherited direction, and logical field layout. Labels, helper text, and tag chips mirror without physical left/right styling.
27
+
28
+ ## Accessibility
29
+
30
+ Connect labels and helper/error text through component props. Use visible error text with `hasError` rather than color alone.
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ npx banhaten add textarea
36
+ ```
37
+
38
+ ## Examples
39
+
40
+ Primary registry example: `examples/textarea-demo.tsx`.
41
+
42
+ Open the live component page or run `npx banhaten docs textarea` to inspect source files, install command, and examples.
43
+
44
+ ## RTL Rules
45
+
46
+ - `inheritsDirection`: true
47
+ - `textAlignment`: Uses text-start and dir="auto" so Arabic and English content align naturally.
48
+ - `spacing`: Uses inherited direction and flex order so labels, helper icons, and tag chips mirror without physical left/right rules.
49
+
50
50
  <!-- registry-contract:start -->
51
51
  ## Registry Contract
52
52
 
@@ -60,5 +60,5 @@ This table is generated from `registry/index.json`; edit the component-owned sou
60
60
  | `registryDependencies` | None |
61
61
  | `modes` | `default`, `tags` |
62
62
  | `states` | `placeholder`, `filled`, `disabled` |
63
- | `tokens` | `--bh-bg-accent-blue-soft`, `--bh-border-danger-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-focus`, `--bh-border-input`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-accent-blue-strong`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-subtle`, `--bh-control-md`, `--bh-font-weight-semibold`, `--bh-icon-stroke-225`, `--bh-icon-stroke-250`, `--bh-interactive-input-default`, `--bh-interactive-input-disabled`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-opacity-0`, `--bh-opacity-30`, `--bh-opacity-50`, `--bh-radius-full`, `--bh-space-xs-4`, `--bh-text-body-md-regular-font-size`, `--bh-text-body-md-regular-font-weight`, `--bh-text-body-md-regular-letter-spacing`, `--bh-text-body-md-regular-line-height`, `--bh-text-body-sm-medium-font-size`, `--bh-text-body-sm-medium-font-weight`, `--bh-text-body-sm-medium-letter-spacing`, `--bh-text-body-sm-medium-line-height`, `--bh-text-body-xs-medium-font-size`, `--bh-text-body-xs-medium-font-weight`, `--bh-text-body-xs-medium-letter-spacing`, `--bh-text-body-xs-medium-line-height`, `--bh-text-body-xs-regular-font-size`, `--bh-text-body-xs-regular-font-weight`, `--bh-text-body-xs-regular-letter-spacing`, `--bh-text-body-xs-regular-line-height`, `--bh-textarea-border`, `--bh-textarea-close-button-size`, `--bh-textarea-close-icon-size`, `--bh-textarea-focus-ring-inset`, `--bh-textarea-focus-ring-width`, `--bh-textarea-gap`, `--bh-textarea-helper-icon-size`, `--bh-textarea-icon-size`, `--bh-textarea-inline-gap`, `--bh-textarea-min-height`, `--bh-textarea-padding`, `--bh-textarea-radius`, `--bh-textarea-tag-avatar-font-size`, `--bh-textarea-tag-avatar-size`, `--bh-textarea-tag-height`, `--bh-textarea-width`, `--shadow-component-default`, `--shadow-textarea` |
63
+ | `tokens` | `--bh-bg-accent-blue-soft`, `--bh-border-danger-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-focus`, `--bh-border-input`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-accent-blue-strong`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-subtle`, `--bh-control-md`, `--bh-font-weight-semibold`, `--bh-icon-stroke-225`, `--bh-icon-stroke-250`, `--bh-interactive-input-default`, `--bh-interactive-input-disabled`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-opacity-0`, `--bh-opacity-30`, `--bh-opacity-50`, `--bh-radius-full`, `--bh-space-xs-4`, `--bh-text-body-md-regular-font-size`, `--bh-text-body-md-regular-font-weight`, `--bh-text-body-md-regular-letter-spacing`, `--bh-text-body-md-regular-line-height`, `--bh-text-body-sm-medium-font-size`, `--bh-text-body-sm-medium-font-weight`, `--bh-text-body-sm-medium-letter-spacing`, `--bh-text-body-sm-medium-line-height`, `--bh-text-body-xs-medium-font-size`, `--bh-text-body-xs-medium-font-weight`, `--bh-text-body-xs-medium-letter-spacing`, `--bh-text-body-xs-medium-line-height`, `--bh-text-body-xs-regular-font-size`, `--bh-text-body-xs-regular-font-weight`, `--bh-text-body-xs-regular-letter-spacing`, `--bh-text-body-xs-regular-line-height`, `--bh-textarea-border`, `--bh-textarea-close-button-size`, `--bh-textarea-close-icon-size`, `--bh-textarea-focus-ring-inset`, `--bh-textarea-focus-ring-width`, `--bh-textarea-gap`, `--bh-textarea-helper-icon-size`, `--bh-textarea-icon-size`, `--bh-textarea-inline-gap`, `--bh-textarea-min-height`, `--bh-textarea-padding`, `--bh-textarea-radius`, `--bh-textarea-tag-avatar-font-size`, `--bh-textarea-tag-avatar-size`, `--bh-textarea-tag-height`, `--bh-textarea-width`, `--elevation-component-default`, `--elevation-textarea` |
64
64
  <!-- registry-contract:end -->
@@ -0,0 +1,72 @@
1
+ # Thinking Reasoning
2
+
3
+ `ThinkingReasoning` is an animated, collapsible reasoning block. While the agent thinks, a shimmering label sits above sentences that reveal in sequence and auto-scroll behind soft fades. Once the agent is done, the block folds into a "Thought for Ns" summary that unfolds the full, scrollable reasoning on demand.
4
+
5
+ The component is data-driven: append sentences to `steps` as they arrive and flip `status` to `done` when the model stops. Scripted timers belong in examples, not in the component.
6
+
7
+ ## API
8
+
9
+ ```tsx
10
+ import { ThinkingReasoning } from "@/components/ui/thinking-reasoning"
11
+
12
+ <ThinkingReasoning
13
+ duration={5}
14
+ status={done ? "done" : "thinking"}
15
+ steps={sentences}
16
+ />
17
+ ```
18
+
19
+ | Prop | Type | Default | Description |
20
+ | --- | --- | --- | --- |
21
+ | `steps` | `readonly string[]` | – | Reasoning sentences in arrival order. Each row clamps to two lines. |
22
+ | `status` | `"thinking" \| "done"` | `"thinking"` | Thinking keeps the block open and auto-scrolling; done folds it into the summary. |
23
+ | `duration` | `number` | measured | Seconds shown in the summary. Measured from the first thinking render when omitted; a block that mounts already done shows the verb alone. |
24
+ | `open` / `defaultOpen` / `onOpenChange` | `boolean` | `false` | Controls whether the finished reasoning is unfolded. |
25
+ | `reserveSpace` | `boolean` | `false` | Keeps the block height stable while folding so content below does not jump. |
26
+ | `labels` | `Partial<ThinkingReasoningLabels>` | English | `thinking`, `thought`, and `duration(seconds)` copy. The finished summary also names the toggle. |
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ npx banhaten add thinking-reasoning
32
+ ```
33
+
34
+ ## Examples
35
+
36
+ Primary registry example: `examples/thinking-reasoning-demo.tsx`.
37
+
38
+ ## Token Contract
39
+
40
+ Width and the capped viewport come from `--bh-thinking-reasoning-width`, `--bh-thinking-reasoning-max-height`, and `--bh-thinking-reasoning-fade`. Sentences use the `body-xs` scale, the header uses `body-xs-medium`, and colors resolve through `--bh-content-subtle` for the verb and sentences and `--bh-content-muted` for the duration and chevron. Motion uses the `--bh-duration-*` foundation tokens with `--bh-easing-emphasized`.
41
+
42
+ Covered source files: `components/thinking-reasoning.tsx`, `components/thinking-reasoning.css`, and the `collapsible` and `shimmer-text` registry dependencies.
43
+
44
+ ## RTL Rules
45
+
46
+ - The block inherits document direction; the header, chevron, and sentence text use logical alignment.
47
+ - Auto-scroll, fades, and the fold are vertical and therefore direction-neutral.
48
+
49
+ ## Accessibility
50
+
51
+ The header is a Collapsible trigger with `aria-expanded` and `aria-controls`, and folded reasoning unmounts after its closing animation. It is disabled while thinking, when there is nothing to toggle, and once done becomes the summary toggle, named by the summary it shows, such as "Thought for 5s". The live label announces the thinking state politely. When unfolded, the reasoning viewport is keyboard scrollable. The reveal, fade, and fold animations collapse to instant changes under `prefers-reduced-motion`.
52
+
53
+ <!-- registry-contract:start -->
54
+ ## Registry Contract
55
+
56
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
57
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
58
+
59
+ | Field | Values |
60
+ | --- | --- |
61
+ | `supportedExports` | `components/thinking-reasoning.tsx: ThinkingReasoning` |
62
+ | `parts` | `ThinkingReasoning` |
63
+ | `registryDependencies` | `collapsible`, `shimmer-text` |
64
+ | `props.steps` | `readonly string[]; default null; Reasoning sentences in arrival order; append to stream new ones.` |
65
+ | `props.status` | `"thinking" \| "done"; default "thinking"; Thinking keeps the block open and auto-scrolling; done folds it into the summary.` |
66
+ | `props.duration` | `number; default "measured"; Seconds shown in the summary; measured from mount when omitted.` |
67
+ | `props.open` | `boolean; default "false"; Controls whether the finished reasoning is unfolded.` |
68
+ | `props.reserveSpace` | `boolean; default "false"; Keeps the block height stable while folding so content below does not jump.` |
69
+ | `props.labels` | `Partial<ThinkingReasoningLabels>; default "English"; Localized thinking, thought, and duration copy; the finished summary also names the toggle.` |
70
+ | `states` | `thinking`, `done`, `open`, `closed` |
71
+ | `tokens` | `--bh-content-muted`, `--bh-content-subtle`, `--bh-duration-fast`, `--bh-duration-moderate`, `--bh-duration-slow`, `--bh-duration-slower`, `--bh-easing-emphasized`, `--bh-easing-standard`, `--bh-font-family`, `--bh-icon-stroke-180`, `--bh-opacity-0`, `--bh-opacity-100`, `--bh-radius-sm-4`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-text-body-xs-medium-font-size`, `--bh-text-body-xs-medium-font-weight`, `--bh-text-body-xs-medium-letter-spacing`, `--bh-text-body-xs-medium-line-height`, `--bh-text-body-xs-regular-font-size`, `--bh-text-body-xs-regular-font-weight`, `--bh-text-body-xs-regular-letter-spacing`, `--bh-text-body-xs-regular-line-height`, `--bh-thinking-reasoning-fade`, `--bh-thinking-reasoning-max-height`, `--bh-thinking-reasoning-width`, `--elevation-component-focus-ring` |
72
+ <!-- registry-contract:end -->