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,60 +1,111 @@
1
- # Input
2
-
3
- Input is the text-entry field primitive for forms, filters, search, numeric entry, tags, shortcuts, add-ons, and action-adorned fields. It supports default and soft variants, md/lg sizing, helper and error text, and RTL-safe slot placement.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <Input label="Email" placeholder="name@example.com" />
9
- <Input state="error" label="Amount" message="Enter a valid amount" />
10
- ```
11
-
12
- | Prop | Type / values | Default | Notes |
13
- | --- | --- | --- | --- |
14
- | `kind` | `default`, `shortcut`, `add-on`, `inline-add-on`, `tags`, `inline-tags`, `trailing-dropdown`, `leading-dropdown`, `quantity`, `quantity-2`, `trailing-button`, `leading-button` | `default` | Selects the input composition. |
15
- | `variant` | `default`, `soft` | `default` | Selects the input surface. |
16
- | `size` | `md`, `lg` | `lg` | Selects the control height. |
17
- | `state` | `default`, `filled`, `error`, `disabled` | `default` | Selects the visual state. |
18
- | `label`, `message` | `ReactNode` | `null` | Their presence enables the corresponding text rows unless explicitly disabled. |
19
- | `hasLeadingIcon` | `boolean` | `false` | Set true to show the default at-sign icon. |
20
- | `leadingIcon` | `ReactNode \| false` | `null` | A node enables the leading slot; false always removes it. |
21
- | `hasInformationIcon` | `boolean` | `false` | Set true to show the default information icon. |
22
- | `trailingIcon` | `ReactNode \| false` | `null` | A node enables the trailing slot; false always removes it. |
23
-
24
- ## Migration
25
-
26
- Input no longer adds the default at-sign or information icon when their props are omitted. Add `hasLeadingIcon` or `hasInformationIcon` to retain either previous default, or supply a custom `leadingIcon` or `trailingIcon` to enable that slot. Explicit `false` always removes the corresponding slot.
27
-
28
- ## Token Contract
29
-
30
- Input consumes Banhaten field, control, typography, spacing, border, radius, content, disabled, error, and focus tokens. Add-on and button segments should use logical borders and shared field tokens.
31
-
32
- ## RTL
33
-
34
- Input uses logical start/end slots and `text-start`. Labels, values, add-ons, tags, and helper text use `dir="auto"` where string copy is rendered.
35
-
36
- ## Accessibility
37
-
38
- Connect labels and helper/error text through the component props when possible. Use `state="error"` with visible error copy instead of relying only on red borders.
39
-
40
- ## Install
41
-
42
- ```bash
43
- npx banhaten add input
44
- ```
45
-
46
- ## Examples
47
-
48
- Primary registry example: `examples/input-demo.tsx`.
49
-
50
- Open the live component page or run `npx banhaten docs input` to inspect source files, install command, and examples.
51
-
52
- ## RTL Rules
53
-
54
- - `inheritsDirection`: true
55
- - `textAlignment`: Uses text-start and dir="auto" so Arabic and English labels, values, add-ons, tags, and helper text align naturally.
56
- - `spacing`: Uses logical start/end borders and inherited direction so leading and trailing segments mirror in RTL.
57
-
1
+ # Input
2
+
3
+ Input is the text-entry field primitive for forms, filters, search, numeric entry, tags, shortcuts, add-ons, and action-adorned fields. It supports default and soft variants, md/lg sizing, helper and error text, and RTL-safe slot placement.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <Input label="Email" placeholder="name@example.com" />
9
+ <Input label="Email" isRequired placeholder="name@example.com" />
10
+ <Input state="error" label="Amount" message="Enter a valid amount" />
11
+ ```
12
+
13
+ | Prop | Type / values | Default | Notes |
14
+ | --- | --- | --- | --- |
15
+ | `kind` | `default`, `shortcut`, `add-on`, `inline-add-on`, `tags`, `inline-tags`, `trailing-dropdown`, `leading-dropdown`, `quantity`, `quantity-2`, `trailing-button`, `leading-button` | `default` | Selects the input composition. |
16
+ | `variant` | `default`, `soft` | `default` | Selects the input surface. |
17
+ | `size` | `md`, `lg` | `lg` | Selects the control height. |
18
+ | `state` | `default`, `filled`, `error`, `disabled` | `default` | Selects the visual state. |
19
+ | `label`, `message` | `ReactNode` | `null` | Their presence enables the corresponding text rows unless explicitly disabled. |
20
+ | `isRequired` | `boolean` | `false` | Shows the required marker and sets `aria-required="true"` without enabling native browser validation. Use the native `required` prop when constraint validation is intended. |
21
+ | `hasLeadingIcon` | `boolean` | `false` | Set true to show the default at-sign icon. |
22
+ | `leadingIcon` | `ReactNode \| false` | `null` | A node enables the 20px leading slot; direct SVG/image glyphs normalize to 16px. `false` removes it. |
23
+ | `hasInformationIcon` | `boolean` | `false` | Set true to show the default information icon. |
24
+ | `trailingIcon` | `ReactNode \| false` | `null` | A node enables the trailing slot; false always removes it. |
25
+ | `shortcutKeys` | `readonly string[]` | `["Mod", "K"]` | For `kind="shortcut"`, renders one compact, platform-aware Shortcut chip. |
26
+ | `shortcut` | `ReactNode` | `null` | Deprecated compact-chip content escape hatch; prefer `shortcutKeys`. |
27
+ | `buttonProps` | `InputActionButtonProps` | `undefined` | Native button events, ref, disabled state, class name, and ARIA attributes for button and dropdown kinds. Defaults to `type="button"`. |
28
+ | `decreaseButtonProps`, `increaseButtonProps` | `InputStepperButtonProps` | `undefined` | Native stepper-button props, excluding children and type. Override `aria-label` for localization. Calling `preventDefault()` in `onClick` cancels the step. |
29
+ | `value`, `defaultValue`, `onChange` | Native input props | `undefined` | Quantity buttons and typing use the same `onChange` contract. Use `value` with `onChange` for controlled fields, or `defaultValue` for uncontrolled fields. |
30
+ | `min`, `max`, `step` | Native number-input props | Native defaults | Quantity kinds always render `type="number"` and use browser stepping rules. With `step="any"`, the buttons step by one while typing remains unrestricted. |
31
+
32
+ ## Quantity and actions
33
+
34
+ ```tsx
35
+ const [quantity, setQuantity] = React.useState("1")
36
+
37
+ <Input
38
+ kind="quantity"
39
+ label="Quantity"
40
+ quantityLabel="Quantity"
41
+ min={0}
42
+ max={10}
43
+ step={1}
44
+ value={quantity}
45
+ onChange={(event) => setQuantity(event.currentTarget.value)}
46
+ />
47
+
48
+ <Input
49
+ kind="trailing-button"
50
+ label="Search"
51
+ buttonLabel="Search"
52
+ value={query}
53
+ onChange={(event) => setQuery(event.currentTarget.value)}
54
+ buttonProps={{ onClick: () => runSearch(query) }}
55
+ />
56
+ ```
57
+
58
+ Quantity buttons do not submit forms. They update uncontrolled values directly,
59
+ notify `onInput` and `onChange`, and let the parent accept or reject a controlled
60
+ change. Steps that cannot move within the bounds emit no change. `disabled`,
61
+ `state="disabled"`, and `readOnly` disable both steppers; per-button `disabled`
62
+ can restrict one direction.
63
+
64
+ Dropdown kinds expose a trigger. Connect the popup action and its accessibility
65
+ state through `buttonProps.onClick`, `aria-haspopup`, `aria-expanded`,
66
+ `aria-controls`, and `ref`. For a menu library that composes its trigger with
67
+ `asChild`, use `InputGroup` with `InputGroupButton` and the library's trigger.
68
+ Button events bubble normally and retain button focus.
69
+
70
+ ## Migration
71
+
72
+ Input no longer adds the default at-sign or information icon when their props are omitted. Add `hasLeadingIcon` or `hasInformationIcon` to retain either previous default, or supply a custom `leadingIcon` or `trailingIcon` to enable that slot. Explicit `false` always removes the corresponding slot.
73
+
74
+ ## Sizing rule
75
+
76
+ Use Input without a `size` or `density` override in standard product UI. The inherited default is `lg` (36px), and it is the expected treatment for forms, search, filters, and verification flows. Use `density="compact"` only when the surrounding context is genuinely constrained, such as a dense desktop table or a compact toolbar, and apply the same semantic density to the other controls in that row. Do not reduce inputs merely to make a preview or card composition fit.
77
+
78
+ ## Token Contract
79
+
80
+ Input consumes Banhaten field, control, typography, spacing, border, radius, content, disabled, error, and focus tokens. Its default size is `lg` (36px); shortcut Inputs use the Figma 8px inline padding, 20px icon slot, 16px glyph, and shared compact Shortcut. Add-on and button segments should use logical borders and shared field tokens.
81
+
82
+ ## RTL
83
+
84
+ Input uses logical start/end slots and `text-start`. Labels, values, add-ons, tags, and helper text use `dir="auto"` where string copy is rendered.
85
+
86
+ ## Accessibility
87
+
88
+ Connect labels and helper/error text through the component props when possible. `isRequired` communicates the required state to assistive technology without changing form-submission behavior; use native `required` when the browser should enforce the constraint. Use `state="error"` with visible error copy instead of relying only on red borders.
89
+
90
+ ## Install
91
+
92
+ ```bash
93
+ npx banhaten add input
94
+ ```
95
+
96
+ ## Examples
97
+
98
+ Primary registry example: `examples/input-demo.tsx`.
99
+ Controlled quantity and action example: `examples/input-actions-demo.tsx`.
100
+
101
+ Open the live component page or run `npx banhaten docs input` to inspect source files, install command, and examples.
102
+
103
+ ## RTL Rules
104
+
105
+ - `inheritsDirection`: true
106
+ - `textAlignment`: Uses text-start and dir="auto" so Arabic and English labels, values, add-ons, tags, and helper text align naturally.
107
+ - `spacing`: Uses logical start/end borders and inherited direction so leading and trailing segments mirror in RTL.
108
+
58
109
  <!-- registry-contract:start -->
59
110
  ## Registry Contract
60
111
 
@@ -66,19 +117,24 @@ This table is generated from `registry/index.json`; edit the component-owned sou
66
117
  | `supportedExports` | `components/input-content.ts: getInputDefaultValue, getInputHelperText, getInputPlaceholder, getInputTags, inputCopy`, `components/input.tsx: Input, inputContent, inputControl, inputRoot, inputSurface` |
67
118
  | `parts` | `Input` |
68
119
  | `registryDependencies` | `kbd` |
120
+ | `props.buttonProps` | `InputActionButtonProps; default null; Native button props for leading/trailing button and dropdown kinds, including onClick, keyboard handlers, ref, disabled, and ARIA attributes. Defaults to type=button; consumers supply the action or popup.` |
121
+ | `props.decreaseButtonProps` | `InputStepperButtonProps; default null; Native props for the decrease button, excluding children and type. Supports localized aria-label, ref, and onClick; preventDefault cancels the step. Field disabled and readOnly always disable the stepper.` |
122
+ | `props.increaseButtonProps` | `InputStepperButtonProps; default null; Native props for the increase button, excluding children and type. Supports localized aria-label, ref, and onClick; preventDefault cancels the step. Field disabled and readOnly always disable the stepper.` |
123
+ | `props.onChange` | `React.ChangeEventHandler<HTMLInputElement>; default null; Receives native input changes from typing and quantity buttons. Quantity kinds use type=number, respect min/max/step, and support controlled value or uncontrolled defaultValue. step=any uses one-unit button increments.` |
69
124
  | `props.density` | `"compact" \| "default" \| "comfortable"; default "default"; Preferred cross-component sizing contract. Overrides the legacy size prop with 32px, 36px, or 40px control heights.` |
70
125
  | `props.hasLeadingIcon` | `boolean; default false; Deprecated compatibility alias for showAtSign.` |
71
- | `props.leadingIcon` | `React.ReactNode \| false; default null; Supplies and enables a custom leading icon; false always removes the leading slot.` |
126
+ | `props.leadingIcon` | `React.ReactNode \| false; default null; Supplies and enables a custom 16px glyph inside the shared 20px leading slot; false always removes the slot.` |
72
127
  | `props.hasInformationIcon` | `boolean; default false; Deprecated compatibility alias for showInfo.` |
128
+ | `props.isRequired` | `boolean; default false; Shows the required marker and exposes aria-required on the input without enabling native browser validation. Use the native required prop when constraint validation is intended.` |
73
129
  | `props.trailingIcon` | `React.ReactNode \| false; default null; Supplies and enables a custom trailing icon; false always removes the information slot.` |
74
130
  | `props.showAtSign` | `boolean; default false; Explicitly shows the semantic at-sign affordance when no leadingIcon is supplied.` |
75
131
  | `props.showInfo` | `boolean; default false; Explicitly shows the semantic information affordance when no trailingIcon is supplied.` |
76
- | `props.shortcutKeys` | `readonly string[]; default "Mod,K"; Renders the shortcut kind with shared Kbd keycaps. Use Mod for a platform-aware primary modifier.` |
77
- | `props.shortcut` | `React.ReactNode; default null; Deprecated single-keycap escape hatch. Prefer shortcutKeys for a structured shortcut chord.` |
132
+ | `props.shortcutKeys` | `readonly string[]; default "Mod,K"; Renders the shortcut kind as one compact platform-aware Shortcut chip. Use Mod for the primary modifier.` |
133
+ | `props.shortcut` | `React.ReactNode; default null; Deprecated compact-chip content escape hatch. Prefer shortcutKeys for a structured platform-aware chord.` |
78
134
  | `densities` | `compact`, `default`, `comfortable` |
79
135
  | `kinds` | `default`, `shortcut`, `add-on`, `inline-add-on`, `tags`, `inline-tags`, `trailing-dropdown`, `leading-dropdown`, `quantity`, `quantity-2`, `trailing-button`, `leading-button` |
80
136
  | `sizes` | `md`, `lg`, `comfortable` |
81
137
  | `states` | `default`, `filled`, `error`, `disabled` |
82
- | `tokens` | `--bh-border-danger-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-input`, `--bh-border-width-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-subtle`, `--bh-control-md`, `--bh-icon-stroke-225`, `--bh-input-border`, `--bh-input-chevron-size`, `--bh-input-comfortable-height`, `--bh-input-comfortable-padding-x`, `--bh-input-content-gap`, `--bh-input-helper-gap`, `--bh-input-icon-size`, `--bh-input-info-icon-size`, `--bh-input-inline-gap`, `--bh-input-inline-tags-gap`, `--bh-input-label-gap`, `--bh-input-lg-height`, `--bh-input-lg-padding-x`, `--bh-input-md-height`, `--bh-input-md-padding-x`, `--bh-input-radius`, `--bh-input-segment-gap`, `--bh-input-segment-padding-x`, `--bh-input-stepper-icon-size`, `--bh-input-stepper-width`, `--bh-input-tag-height`, `--bh-input-tag-padding-x`, `--bh-input-width`, `--bh-interactive-input-default`, `--bh-interactive-input-disabled`, `--bh-interactive-input-soft`, `--bh-interactive-input-soft-disabled`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-interactive-secondary-hover`, `--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-z-raised`, `--shadow-component-default`, `--shadow-input`, `--shadow-input-disabled-overlay`, `--shadow-input-focus-overlay`, `--shadow-input-focus-ring`, `--shadow-input-focus-surface`, `--shadow-input-overlay`, `--shadow-input-surface` |
138
+ | `tokens` | `--bh-border-danger-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-input`, `--bh-border-width-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-subtle`, `--bh-control-md`, `--bh-icon-stroke-225`, `--bh-input-border`, `--bh-input-chevron-size`, `--bh-input-comfortable-height`, `--bh-input-comfortable-padding-x`, `--bh-input-content-gap`, `--bh-input-helper-gap`, `--bh-input-icon-size`, `--bh-input-icon-slot-size`, `--bh-input-info-icon-size`, `--bh-input-inline-gap`, `--bh-input-inline-tags-gap`, `--bh-input-label-gap`, `--bh-input-lg-height`, `--bh-input-lg-padding-x`, `--bh-input-md-height`, `--bh-input-md-padding-x`, `--bh-input-radius`, `--bh-input-segment-gap`, `--bh-input-segment-padding-x`, `--bh-input-stepper-icon-size`, `--bh-input-stepper-width`, `--bh-input-tag-height`, `--bh-input-tag-padding-x`, `--bh-input-width`, `--bh-interactive-input-default`, `--bh-interactive-input-disabled`, `--bh-interactive-input-soft`, `--bh-interactive-input-soft-disabled`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-interactive-secondary-hover`, `--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-z-raised`, `--elevation-component-default`, `--elevation-input`, `--elevation-input-disabled-overlay`, `--elevation-input-focus-overlay`, `--elevation-input-focus-ring`, `--elevation-input-focus-surface`, `--elevation-input-overlay`, `--elevation-input-surface` |
83
139
  | `variants` | `default`, `soft` |
84
140
  <!-- registry-contract:end -->
@@ -1,59 +1,61 @@
1
- # Item
2
-
3
- Item is Banhaten’s composable row primitive for lists, settings, search results, files, and compact summaries. It keeps media, copy, and actions on one logical layout contract without embedding product behavior or placeholder content.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <ItemGroup aria-label="Recent documents">
9
- <Item role="listitem" variant="outline">
10
- <ItemMedia><FileTextIcon aria-hidden="true" /></ItemMedia>
11
- <ItemContent>
12
- <ItemTitle>Launch checklist</ItemTitle>
13
- <ItemDescription>Updated five minutes ago</ItemDescription>
14
- </ItemContent>
15
- <ItemActions>{/* real controls */}</ItemActions>
16
- </Item>
17
- </ItemGroup>
18
- ```
19
-
20
- Use `asChild` when the whole row should be a native link or button. Interactive controls inside `ItemActions` must retain their own accessible names.
21
-
22
- ## Variants
23
-
24
- | Prop | Values |
25
- | --- | --- |
26
- | `variant` | `default`, `muted`, `outline` |
27
- | `size` | `sm`, `md`, `lg` |
28
- | `disabled` | `boolean` |
29
- | `ItemMedia variant` | `icon`, `avatar`, `image` |
30
-
31
- ## Install
32
-
33
- ```bash
34
- npx banhaten add item
35
- ```
36
-
37
- ## Accessibility
38
-
39
- `ItemGroup` defaults to `role="list"`; give rows `role="listitem"` when using the default non-semantic `div`. Prefer native anchors or buttons through `asChild` for interactive rows. Disabled styling maps to `aria-disabled` and does not invent click behavior.
40
-
41
- ## RTL Rules
42
-
43
- - `inheritsDirection`: true
44
- - `layout`: media, content, and actions follow logical flex order.
45
- - `textDirection`: title and description use `dir="auto"`.
46
-
47
- ## Token Contract
48
-
49
- Every dimension, surface, color, radius, type style, focus treatment, and transition resolves through Banhaten tokens. Covered source file: `components/item.tsx`.
50
-
51
- ## Examples
52
-
53
- Primary registry example: `examples/item-demo.tsx`.
54
-
55
- Open the live component page or run `npx banhaten docs item` to inspect source files, install command, and examples.
56
-
1
+ # Item
2
+
3
+ Item is Banhaten’s composable row primitive for lists, settings, search results, files, and compact summaries. It keeps media, copy, and actions on one logical layout contract without embedding product behavior or placeholder content.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <ItemGroup aria-label="Recent documents">
9
+ <Item role="listitem" variant="outline">
10
+ <ItemMedia><FileTextIcon aria-hidden="true" /></ItemMedia>
11
+ <ItemContent>
12
+ <ItemTitle>Launch checklist</ItemTitle>
13
+ <ItemDescription>Updated five minutes ago</ItemDescription>
14
+ </ItemContent>
15
+ <ItemActions>{/* real controls */}</ItemActions>
16
+ </Item>
17
+ </ItemGroup>
18
+ ```
19
+
20
+ Use `asChild` when the whole row should be a native link or button. Interactive controls inside `ItemActions` must retain their own accessible names.
21
+
22
+ ## Variants
23
+
24
+ | Prop | Values |
25
+ | --- | --- |
26
+ | `variant` | `default`, `muted`, `outline` |
27
+ | `size` | `sm`, `md`, `lg` |
28
+ | `disabled` | `boolean` |
29
+ | `ItemMedia variant` | `icon`, `avatar`, `image` |
30
+
31
+ Default `ItemMedia` glyphs are 18px while their 20px layout footprint remains stable inside the media container.
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ npx banhaten add item
37
+ ```
38
+
39
+ ## Accessibility
40
+
41
+ `ItemGroup` defaults to `role="list"`; give rows `role="listitem"` when using the default non-semantic `div`. Prefer native anchors or buttons through `asChild` for interactive rows. Disabled styling maps to `aria-disabled` and does not invent click behavior.
42
+
43
+ ## RTL Rules
44
+
45
+ - `inheritsDirection`: true
46
+ - `layout`: media, content, and actions follow logical flex order.
47
+ - `textDirection`: title and description use `dir="auto"`.
48
+
49
+ ## Token Contract
50
+
51
+ Every dimension, surface, color, radius, type style, focus treatment, and transition resolves through Banhaten tokens. Covered source file: `components/item.tsx`.
52
+
53
+ ## Examples
54
+
55
+ Primary registry example: `examples/item-demo.tsx`.
56
+
57
+ Open the live component page or run `npx banhaten docs item` to inspect source files, install command, and examples.
58
+
57
59
  <!-- registry-contract:start -->
58
60
  ## Registry Contract
59
61
 
@@ -67,6 +69,6 @@ This table is generated from `registry/index.json`; edit the component-owned sou
67
69
  | `registryDependencies` | None |
68
70
  | `features` | `media slot`, `content slots`, `action slot`, `asChild composition`, `disabled semantics` |
69
71
  | `sizes` | `sm`, `md`, `lg` |
70
- | `tokens` | `--bh-bg-default`, `--bh-bg-neutral-default`, `--bh-bg-neutral-soft`, `--bh-bg-neutral-subtle`, `--bh-bg-raised`, `--bh-bg-raised-hover`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-on-color`, `--bh-content-subtle`, `--bh-interactive-ghost-hover`, `--bh-item-actions-gap`, `--bh-item-content-gap`, `--bh-item-gap`, `--bh-item-group-gap`, `--bh-item-icon-size`, `--bh-item-media-radius`, `--bh-item-media-size`, `--bh-item-min-height-lg`, `--bh-item-min-height-md`, `--bh-item-min-height-sm`, `--bh-item-padding-x`, `--bh-item-padding-y`, `--bh-item-radius`, `--bh-radius-full`, `--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-regular-font-size`, `--bh-text-body-sm-regular-font-weight`, `--bh-text-body-sm-regular-letter-spacing`, `--bh-text-body-sm-regular-line-height`, `--shadow-button-focus` |
72
+ | `tokens` | `--bh-bg-default`, `--bh-bg-neutral-default`, `--bh-bg-neutral-soft`, `--bh-bg-neutral-subtle`, `--bh-bg-raised`, `--bh-bg-raised-hover`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-on-color`, `--bh-content-subtle`, `--bh-interactive-ghost-hover`, `--bh-item-actions-gap`, `--bh-item-content-gap`, `--bh-item-gap`, `--bh-item-group-gap`, `--bh-item-icon-size`, `--bh-item-icon-slot-size`, `--bh-item-media-radius`, `--bh-item-media-size`, `--bh-item-min-height-lg`, `--bh-item-min-height-md`, `--bh-item-min-height-sm`, `--bh-item-padding-x`, `--bh-item-padding-y`, `--bh-item-radius`, `--bh-radius-full`, `--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-regular-font-size`, `--bh-text-body-sm-regular-font-weight`, `--bh-text-body-sm-regular-letter-spacing`, `--bh-text-body-sm-regular-line-height`, `--elevation-button-focus` |
71
73
  | `variants` | `default`, `muted`, `outline` |
72
74
  <!-- registry-contract:end -->
@@ -1,48 +1,52 @@
1
- # Kbd
2
-
3
- Kbd renders compact keyboard hints for shortcuts, command rows, and form help text.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <Kbd>⌘</Kbd>
9
- <Kbd>K</Kbd>
10
- <Kbd size="md">Shift</Kbd>
11
- ```
12
-
13
- | Prop | Values |
14
- | --- | --- |
15
- | `size` | `sm`, `md` |
16
-
17
- ## Token Contract
18
-
19
- Kbd uses Banhaten border, soft interactive background, radius, body-xs typography, and button shadow tokens.
20
-
21
- ## RTL
22
-
23
- Kbd is direction-neutral. Use surrounding text direction for shortcut descriptions.
24
-
25
- ## Accessibility
26
-
27
- Use Kbd as supporting text, not as the only label for an action.
28
-
29
- ## Install
30
-
31
- ```bash
32
- npx banhaten add kbd
33
- ```
34
-
35
- ## Examples
36
-
37
- Primary registry example: `examples/kbd-demo.tsx`.
38
-
39
- Open the live component page or run `npx banhaten docs kbd` to inspect source files, install command, and examples.
40
-
41
- ## RTL Rules
42
-
43
- - `inheritsDirection`: false
44
- - `semantics`: Kbd is direction-neutral and should be paired with surrounding text labels.
45
-
1
+ # Kbd
2
+
3
+ Kbd renders physical keyboard keys. Shortcut renders a compact combined hint for Inputs and constrained action rows, while KbdShortcut renders each physical key on its own surface.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <Shortcut keys={["Mod", "K"]} />
9
+ <KbdShortcut keys={["Mod", "K"]} />
10
+ <Kbd>Esc</Kbd>
11
+ <Kbd size="md">Shift</Kbd>
12
+ ```
13
+
14
+ | Prop | Values |
15
+ | --- | --- |
16
+ | `dir` | `ltr` by default on Kbd; override only for localized non-shortcut key names |
17
+ | `size` | `sm`, `md` |
18
+ | `keys` | `readonly string[]`; use `Mod` for Command on Apple platforms and Control elsewhere |
19
+ | `platform` | `auto`, `mac`, `windows`, `linux` |
20
+
21
+ ## Token Contract
22
+
23
+ Kbd uses Banhaten border, soft interactive background, radius, body-xs typography, and button elevation tokens. Shortcut uses the Figma compact contract: 20px height/minimum width, 4px inline padding and radius, body-2xs medium typography, and no keycap elevation.
24
+
25
+ ## RTL
26
+
27
+ Kbd defaults to `dir="ltr"` so physical modifiers and keys keep their canonical order inside RTL interfaces. Surrounding shortcut descriptions retain their own text direction; pass an explicit `dir` only for localized, non-shortcut key names.
28
+
29
+ ## Accessibility
30
+
31
+ Use Kbd as supporting text, not as the only label for an action.
32
+
33
+ ## Install
34
+
35
+ ```bash
36
+ npx banhaten add kbd
37
+ ```
38
+
39
+ ## Examples
40
+
41
+ Primary registry example: `examples/kbd-demo.tsx`.
42
+
43
+ Open the live component page or run `npx banhaten docs kbd` to inspect source files, install command, and examples.
44
+
45
+ ## RTL Rules
46
+
47
+ - `inheritsDirection`: false
48
+ - `semantics`: Kbd defaults to dir="ltr" so physical key order stays stable, while surrounding shortcut descriptions keep their own text direction.
49
+
46
50
  <!-- registry-contract:start -->
47
51
  ## Registry Contract
48
52
 
@@ -51,12 +55,13 @@ This table is generated from `registry/index.json`; edit the component-owned sou
51
55
 
52
56
  | Field | Values |
53
57
  | --- | --- |
54
- | `supportedExports` | `components/kbd.tsx: Kbd, KbdShortcut, kbdVariants` |
55
- | `parts` | `Kbd`, `KbdShortcut` |
58
+ | `supportedExports` | `components/kbd.tsx: Kbd, KbdShortcut, Shortcut, kbdVariants, shortcutVariants` |
59
+ | `parts` | `Kbd`, `KbdShortcut`, `Shortcut` |
56
60
  | `registryDependencies` | None |
57
- | `props.keys` | `readonly string[]; default null; Required by KbdShortcut. Each entry renders as its own keycap; use Mod for the platform primary modifier.` |
61
+ | `props.dir` | `"ltr" \| "rtl" \| "auto"; default "ltr"; Keeps physical key and modifier order stable inside RTL interfaces. Override only for localized non-shortcut key names.` |
62
+ | `props.keys` | `readonly string[]; default null; Used by KbdShortcut and Shortcut. Use Mod for the platform primary modifier; KbdShortcut separates keys while Shortcut combines them.` |
58
63
  | `props.platform` | `"auto" \| "mac" \| "windows" \| "linux"; default "auto"; Resolves Mod to Command on Apple platforms and Control elsewhere.` |
59
64
  | `props.disabled` | `boolean; default false; Uses disabled border, surface, content, and shadow tokens for shortcuts inside disabled controls.` |
60
65
  | `sizes` | `sm`, `md` |
61
- | `tokens` | `--bh-border-default`, `--bh-border-disabled`, `--bh-content-disabled`, `--bh-content-subtle`, `--bh-font-family`, `--bh-interactive-soft-default`, `--bh-interactive-soft-disabled`, `--bh-radius-md-6`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-md-8`, `--bh-space-sm-6`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--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`, `--shadow-button-soft` |
66
+ | `tokens` | `--bh-border-default`, `--bh-border-disabled`, `--bh-content-disabled`, `--bh-content-subtle`, `--bh-font-family`, `--bh-interactive-soft-default`, `--bh-interactive-soft-disabled`, `--bh-radius-md-6`, `--bh-radius-sm-4`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-md-8`, `--bh-space-sm-6`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--bh-text-body-2xs-medium-font-size`, `--bh-text-body-2xs-medium-font-weight`, `--bh-text-body-2xs-medium-letter-spacing`, `--bh-text-body-2xs-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`, `--elevation-button-soft` |
62
67
  <!-- registry-contract:end -->
@@ -1,52 +1,52 @@
1
- # Label
2
-
3
- Label renders accessible control labels with Banhaten typography, required markers, optional text, tone variants, and RTL-safe copy. It is backed by Radix Label.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <Label htmlFor="email" required>
9
- Email address
10
- </Label>
11
- ```
12
-
13
- | Prop | Values |
14
- | --- | --- |
15
- | `htmlFor` | target control id |
16
- | `tone` | `default`, `subtle`, `danger` |
17
- | `required` | `boolean` |
18
- | `optionalText` | `ReactNode` |
19
-
20
- ## Token Contract
21
-
22
- Label consumes Banhaten body-sm, body-xs, content, danger, spacing, and disabled-state tokens.
23
-
24
- ## RTL
25
-
26
- Label uses logical inline spacing and `dir="auto"` for label and optional text.
27
-
28
- ## Accessibility
29
-
30
- Use `htmlFor` for native controls. For complete form rows with description and error text, use `Field`.
31
-
32
- ## Install
33
-
34
- ```bash
35
- npx banhaten add label
36
- ```
37
-
38
- ## Examples
39
-
40
- Primary registry example: `examples/label-demo.tsx`.
41
-
42
- Open the live component page or run `npx banhaten docs label` to inspect source files, install command, and examples.
43
-
44
- ## RTL Rules
45
-
46
- - `inheritsDirection`: true
47
- - `textDirection`: Label and optional text use dir="auto" so Arabic and English labels resolve naturally.
48
- - `spacing`: Uses logical inline spacing between label text, required marker, and optional text.
49
-
1
+ # Label
2
+
3
+ Label renders accessible control labels with Banhaten typography, required markers, optional text, tone variants, and RTL-safe copy. It is backed by Radix Label.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <Label htmlFor="email" required>
9
+ Email address
10
+ </Label>
11
+ ```
12
+
13
+ | Prop | Values |
14
+ | --- | --- |
15
+ | `htmlFor` | target control id |
16
+ | `tone` | `default`, `subtle`, `danger` |
17
+ | `required` | `boolean` |
18
+ | `optionalText` | `ReactNode` |
19
+
20
+ ## Token Contract
21
+
22
+ Label consumes Banhaten body-sm, body-xs, content, danger, spacing, and disabled-state tokens.
23
+
24
+ ## RTL
25
+
26
+ Label uses logical inline spacing and `dir="auto"` for label and optional text.
27
+
28
+ ## Accessibility
29
+
30
+ Use `htmlFor` for native controls. For complete form rows with description and error text, use `Field`.
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ npx banhaten add label
36
+ ```
37
+
38
+ ## Examples
39
+
40
+ Primary registry example: `examples/label-demo.tsx`.
41
+
42
+ Open the live component page or run `npx banhaten docs label` to inspect source files, install command, and examples.
43
+
44
+ ## RTL Rules
45
+
46
+ - `inheritsDirection`: true
47
+ - `textDirection`: Label and optional text use dir="auto" so Arabic and English labels resolve naturally.
48
+ - `spacing`: Uses logical inline spacing between label text, required marker, and optional text.
49
+
50
50
  <!-- registry-contract:start -->
51
51
  ## Registry Contract
52
52