banhaten 0.5.0 → 0.6.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 (290) hide show
  1. package/CHANGELOG.md +177 -139
  2. package/CONTRIBUTING.md +46 -46
  3. package/README.md +192 -192
  4. package/SECURITY.md +15 -15
  5. package/banhaten.config.example.json +11 -11
  6. package/docs/design-spacing.md +13 -13
  7. package/docs/design-system/README.md +22 -22
  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 -245
  16. package/docs/design-system/component-quality-audit-2026-08-20.md +225 -225
  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 +91 -90
  20. package/docs/design-system/components/accordion.md +52 -52
  21. package/docs/design-system/components/activity-feed.md +93 -93
  22. package/docs/design-system/components/activity-heatmap.md +56 -56
  23. package/docs/design-system/components/alert-dialog.md +71 -71
  24. package/docs/design-system/components/alert.md +103 -97
  25. package/docs/design-system/components/app-header.md +97 -0
  26. package/docs/design-system/components/aspect-ratio.md +45 -45
  27. package/docs/design-system/components/attribute.md +101 -89
  28. package/docs/design-system/components/autocomplete.md +75 -75
  29. package/docs/design-system/components/avatar.md +53 -53
  30. package/docs/design-system/components/badge.md +55 -55
  31. package/docs/design-system/components/banner.md +86 -86
  32. package/docs/design-system/components/breadcrumbs.md +181 -177
  33. package/docs/design-system/components/button-group.md +97 -97
  34. package/docs/design-system/components/button.md +80 -80
  35. package/docs/design-system/components/card.md +102 -88
  36. package/docs/design-system/components/carousel.md +46 -46
  37. package/docs/design-system/components/catalog-components.md +46 -46
  38. package/docs/design-system/components/checkbox.md +53 -53
  39. package/docs/design-system/components/collapsible.md +63 -63
  40. package/docs/design-system/components/command.md +61 -61
  41. package/docs/design-system/components/context-menu.md +45 -45
  42. package/docs/design-system/components/date-picker.md +80 -80
  43. package/docs/design-system/components/divider.md +102 -102
  44. package/docs/design-system/components/empty-state.md +56 -56
  45. package/docs/design-system/components/field.md +70 -70
  46. package/docs/design-system/components/file-upload.md +186 -186
  47. package/docs/design-system/components/hover-card.md +47 -47
  48. package/docs/design-system/components/icons.md +48 -48
  49. package/docs/design-system/components/input-group.md +57 -57
  50. package/docs/design-system/components/input-otp.md +56 -56
  51. package/docs/design-system/components/input.md +111 -109
  52. package/docs/design-system/components/item.md +58 -58
  53. package/docs/design-system/components/kbd.md +49 -49
  54. package/docs/design-system/components/label.md +49 -49
  55. package/docs/design-system/components/menu.md +94 -73
  56. package/docs/design-system/components/menubar.md +46 -46
  57. package/docs/design-system/components/modal.md +104 -104
  58. package/docs/design-system/components/native-select.md +53 -53
  59. package/docs/design-system/components/navigation-menu.md +49 -49
  60. package/docs/design-system/components/onboarding-step-list-item.md +81 -81
  61. package/docs/design-system/components/page-header.md +127 -93
  62. package/docs/design-system/components/pagination.md +56 -56
  63. package/docs/design-system/components/popover.md +59 -59
  64. package/docs/design-system/components/progress-slider.md +49 -49
  65. package/docs/design-system/components/progress.md +76 -76
  66. package/docs/design-system/components/radio-card.md +50 -50
  67. package/docs/design-system/components/radio-group.md +56 -56
  68. package/docs/design-system/components/resizable.md +43 -43
  69. package/docs/design-system/components/scroll-area.md +50 -50
  70. package/docs/design-system/components/segmented-control.md +54 -54
  71. package/docs/design-system/components/select.md +68 -64
  72. package/docs/design-system/components/sheet.md +66 -66
  73. package/docs/design-system/components/sidebar.md +167 -111
  74. package/docs/design-system/components/skeleton.md +74 -74
  75. package/docs/design-system/components/slideout.md +64 -64
  76. package/docs/design-system/components/slider.md +62 -62
  77. package/docs/design-system/components/social-button.md +49 -49
  78. package/docs/design-system/components/spinner.md +62 -62
  79. package/docs/design-system/components/steps.md +65 -65
  80. package/docs/design-system/components/table.md +499 -422
  81. package/docs/design-system/components/tabs.md +74 -59
  82. package/docs/design-system/components/tag.md +79 -79
  83. package/docs/design-system/components/textarea.md +49 -49
  84. package/docs/design-system/components/timeline.md +82 -82
  85. package/docs/design-system/components/toast.md +57 -57
  86. package/docs/design-system/components/toggle.md +80 -80
  87. package/docs/design-system/components/toolbar.md +89 -89
  88. package/docs/design-system/components/tooltip.md +92 -92
  89. package/docs/design-system/components/typography.md +18 -18
  90. package/docs/design-system/density-and-elevation.md +65 -65
  91. package/docs/design-system/design-system-test-missing-items.md +368 -368
  92. package/docs/design-system/direction-and-localization.md +23 -23
  93. package/docs/design-system/form-recipes.md +73 -73
  94. package/docs/design-system/gap-promotion-policy.md +21 -21
  95. package/docs/design-system/icons.md +74 -74
  96. package/docs/design-system/installation.md +70 -70
  97. package/docs/design-system/launch-comparison-shadcn.md +98 -98
  98. package/docs/design-system/registry-and-cli.md +64 -64
  99. package/docs/design-system/release-policy.md +30 -30
  100. package/docs/design-system/roadmap.md +14 -14
  101. package/docs/design-system/support-matrix.md +23 -23
  102. package/docs/design-system/tabs.md +54 -54
  103. package/docs/design-system/template-gap-audit.md +32 -32
  104. package/docs/design-system/templates.md +59 -59
  105. package/docs/design-system/token-governance.md +72 -72
  106. package/package.json +98 -98
  107. package/registry/component-contract.json +40 -40
  108. package/registry/components/accordion.tsx +155 -155
  109. package/registry/components/alert-dialog.tsx +297 -297
  110. package/registry/components/alert.tsx +309 -293
  111. package/registry/components/app-header.tsx +151 -0
  112. package/registry/components/aspect-ratio.tsx +30 -30
  113. package/registry/components/attribute.tsx +489 -454
  114. package/registry/components/autocomplete.tsx +598 -598
  115. package/registry/components/avatar.tsx +385 -385
  116. package/registry/components/badge.tsx +630 -629
  117. package/registry/components/button-group.tsx +565 -565
  118. package/registry/components/button.tsx +128 -127
  119. package/registry/components/card.tsx +651 -638
  120. package/registry/components/carousel.tsx +296 -296
  121. package/registry/components/chart.tsx +203 -203
  122. package/registry/components/checkbox.tsx +247 -247
  123. package/registry/components/collapsible.tsx +109 -109
  124. package/registry/components/command.tsx +208 -208
  125. package/registry/components/context-menu.tsx +236 -236
  126. package/registry/components/date-picker.tsx +1289 -1289
  127. package/registry/components/expanded/ActivityFeed.tsx +227 -227
  128. package/registry/components/expanded/ActivityHeatmap.tsx +64 -64
  129. package/registry/components/expanded/Banner.tsx +179 -179
  130. package/registry/components/expanded/Breadcrumbs.tsx +135 -131
  131. package/registry/components/expanded/CatalogComponentsShowcase.tsx +205 -205
  132. package/registry/components/expanded/CatalogDivider.tsx +49 -49
  133. package/registry/components/expanded/EmptyState.tsx +155 -155
  134. package/registry/components/expanded/FileUpload.tsx +543 -543
  135. package/registry/components/expanded/OnboardingStepListItem.tsx +60 -60
  136. package/registry/components/expanded/PageHeader.tsx +209 -179
  137. package/registry/components/expanded/Slideout.tsx +108 -108
  138. package/registry/components/expanded/Steps.tsx +402 -402
  139. package/registry/components/expanded/Table.tsx +1109 -1092
  140. package/registry/components/expanded/Timeline.tsx +203 -203
  141. package/registry/components/expanded/activityFeed.css +248 -248
  142. package/registry/components/expanded/activityHeatmap.css +66 -66
  143. package/registry/components/expanded/banner.css +260 -260
  144. package/registry/components/expanded/breadcrumbs.css +157 -140
  145. package/registry/components/expanded/catalogComponentsShowcase.css +87 -87
  146. package/registry/components/expanded/divider.css +75 -75
  147. package/registry/components/expanded/emptyState.css +111 -111
  148. package/registry/components/expanded/fileUpload.css +457 -457
  149. package/registry/components/expanded/onboardingStepListItem.css +135 -135
  150. package/registry/components/expanded/pageHeader.css +284 -248
  151. package/registry/components/expanded/slideout.css +276 -276
  152. package/registry/components/expanded/steps.css +356 -356
  153. package/registry/components/expanded/table.css +655 -606
  154. package/registry/components/expanded/timeline.css +286 -286
  155. package/registry/components/field.tsx +283 -283
  156. package/registry/components/hover-card.tsx +48 -48
  157. package/registry/components/input-content.ts +107 -107
  158. package/registry/components/input-group.tsx +130 -130
  159. package/registry/components/input-otp.tsx +584 -584
  160. package/registry/components/input.tsx +992 -990
  161. package/registry/components/item.tsx +189 -189
  162. package/registry/components/kbd.tsx +246 -246
  163. package/registry/components/label.tsx +78 -78
  164. package/registry/components/menu.tsx +1091 -978
  165. package/registry/components/menubar.tsx +226 -226
  166. package/registry/components/modal.tsx +872 -872
  167. package/registry/components/native-select.tsx +205 -205
  168. package/registry/components/navigation-menu.tsx +171 -171
  169. package/registry/components/pagination.css +36 -36
  170. package/registry/components/pagination.tsx +560 -560
  171. package/registry/components/popover.tsx +338 -338
  172. package/registry/components/progress-slider.tsx +216 -216
  173. package/registry/components/radio-card.tsx +676 -676
  174. package/registry/components/radio-group.tsx +570 -570
  175. package/registry/components/resizable.tsx +108 -108
  176. package/registry/components/scroll-area.tsx +91 -91
  177. package/registry/components/segmented-control.tsx +87 -87
  178. package/registry/components/select-content.tsx +218 -218
  179. package/registry/components/select.tsx +937 -937
  180. package/registry/components/sheet.tsx +305 -305
  181. package/registry/components/sidebar.tsx +1535 -1433
  182. package/registry/components/skeleton.css +54 -54
  183. package/registry/components/skeleton.tsx +482 -482
  184. package/registry/components/slider.tsx +380 -380
  185. package/registry/components/social-button.tsx +387 -387
  186. package/registry/components/spinner.tsx +78 -78
  187. package/registry/components/table-elements.tsx +287 -128
  188. package/registry/components/tabs.css +246 -222
  189. package/registry/components/tabs.tsx +245 -241
  190. package/registry/components/tag.tsx +423 -423
  191. package/registry/components/textarea.tsx +610 -610
  192. package/registry/components/toast.tsx +136 -136
  193. package/registry/components/toggle.tsx +256 -256
  194. package/registry/components/toolbar.tsx +539 -539
  195. package/registry/components/tooltip.tsx +433 -433
  196. package/registry/examples/alert-demo.tsx +34 -34
  197. package/registry/examples/alert-dialog-demo.tsx +42 -42
  198. package/registry/examples/app-header-demo.tsx +40 -0
  199. package/registry/examples/aspect-ratio-demo.tsx +11 -11
  200. package/registry/examples/attribute-demo.tsx +65 -65
  201. package/registry/examples/autocomplete-demo.tsx +109 -109
  202. package/registry/examples/avatar-demo.tsx +132 -132
  203. package/registry/examples/badge-demo.tsx +69 -69
  204. package/registry/examples/button-demo.tsx +86 -86
  205. package/registry/examples/button-group-demo.tsx +63 -63
  206. package/registry/examples/card-demo.tsx +86 -86
  207. package/registry/examples/carousel-demo.tsx +43 -43
  208. package/registry/examples/chart-demo.tsx +18 -18
  209. package/registry/examples/checkbox-demo.tsx +62 -62
  210. package/registry/examples/collapsible-demo.tsx +16 -16
  211. package/registry/examples/collection-filter-bar-demo.tsx +135 -135
  212. package/registry/examples/command-demo.tsx +42 -42
  213. package/registry/examples/command-palette-demo.tsx +235 -235
  214. package/registry/examples/context-menu-demo.tsx +29 -29
  215. package/registry/examples/control-density-contract-demo.tsx +65 -65
  216. package/registry/examples/date-picker-demo.tsx +127 -127
  217. package/registry/examples/divider-demo.tsx +17 -17
  218. package/registry/examples/expanded/activity-heatmap-demo.tsx +29 -29
  219. package/registry/examples/expanded/banner-demo.tsx +48 -48
  220. package/registry/examples/expanded/breadcrumbs-demo.tsx +59 -59
  221. package/registry/examples/expanded/empty-state-demo.tsx +39 -39
  222. package/registry/examples/expanded/file-upload-demo.tsx +60 -60
  223. package/registry/examples/expanded/onboarding-step-demo.tsx +11 -11
  224. package/registry/examples/expanded/slideout-demo.tsx +15 -15
  225. package/registry/examples/expanded/steps-demo.tsx +29 -29
  226. package/registry/examples/expanded/tabs-demo.tsx +13 -13
  227. package/registry/examples/expanded/timeline-demo.tsx +18 -18
  228. package/registry/examples/field-demo.tsx +51 -51
  229. package/registry/examples/hover-card-demo.tsx +23 -23
  230. package/registry/examples/input-actions-demo.tsx +36 -36
  231. package/registry/examples/input-demo.tsx +87 -87
  232. package/registry/examples/input-group-demo.tsx +16 -16
  233. package/registry/examples/input-otp-demo.tsx +72 -72
  234. package/registry/examples/item-demo.tsx +46 -46
  235. package/registry/examples/kbd-demo.tsx +12 -12
  236. package/registry/examples/label-demo.tsx +20 -20
  237. package/registry/examples/menu-demo.tsx +122 -122
  238. package/registry/examples/menubar-demo.tsx +34 -34
  239. package/registry/examples/modal-demo.tsx +74 -74
  240. package/registry/examples/native-select-demo.tsx +16 -16
  241. package/registry/examples/navigation-menu-demo.tsx +29 -29
  242. package/registry/examples/pagination-demo.tsx +20 -20
  243. package/registry/examples/popover-demo.tsx +547 -547
  244. package/registry/examples/progress-demo.tsx +37 -37
  245. package/registry/examples/progress-slider-demo.tsx +29 -29
  246. package/registry/examples/radio-card-demo.tsx +51 -51
  247. package/registry/examples/radio-group-demo.tsx +62 -62
  248. package/registry/examples/resizable-demo.tsx +22 -22
  249. package/registry/examples/results-toolbar-demo.tsx +44 -44
  250. package/registry/examples/scroll-area-demo.tsx +15 -15
  251. package/registry/examples/segmented-control-demo.tsx +39 -39
  252. package/registry/examples/select-demo.tsx +87 -87
  253. package/registry/examples/sheet-demo.tsx +47 -47
  254. package/registry/examples/sidebar-demo.tsx +101 -101
  255. package/registry/examples/slider-demo.tsx +31 -31
  256. package/registry/examples/social-button-demo.tsx +61 -61
  257. package/registry/examples/spinner-demo.tsx +59 -59
  258. package/registry/examples/tabs-demo.tsx +13 -13
  259. package/registry/examples/tag-demo.tsx +29 -29
  260. package/registry/examples/textarea-demo.tsx +79 -79
  261. package/registry/examples/toast-demo.tsx +35 -35
  262. package/registry/examples/toggle-demo.tsx +59 -59
  263. package/registry/examples/tooltip-demo.tsx +115 -115
  264. package/registry/guidance/USAGE.md +27 -27
  265. package/registry/hooks/use-direction.ts +207 -207
  266. package/registry/index.json +387 -17
  267. package/registry/styles/globals.css +46 -0
  268. package/registry.json +24 -2
  269. package/schema/config.schema.json +51 -51
  270. package/schema/registry.schema.json +194 -194
  271. package/schema/tokens.schema.json +167 -167
  272. package/src/cli/command-line.js +194 -194
  273. package/src/cli/config-editors.js +9 -9
  274. package/src/cli/doctor.js +399 -399
  275. package/src/cli/file-transaction.js +302 -302
  276. package/src/cli/global-css.js +153 -153
  277. package/src/cli/index.js +1002 -1002
  278. package/src/cli/install-plan.js +592 -592
  279. package/src/cli/install-receipt.js +171 -171
  280. package/src/cli/jsonc.js +203 -203
  281. package/src/cli/package-install-state.js +254 -254
  282. package/src/cli/package-manager.js +238 -238
  283. package/src/cli/package-plan.js +185 -185
  284. package/src/cli/package-version.js +97 -97
  285. package/src/cli/registry-query.js +207 -207
  286. package/src/cli/reporting.js +55 -55
  287. package/src/cli/schema-validation.js +19 -19
  288. package/src/cli/source-scanner.js +686 -686
  289. package/src/cli/vite-config.js +478 -478
  290. package/tokens/banhaten.tokens.json +184 -0
@@ -1,60 +1,60 @@
1
- # Input Group
2
-
3
- Input Group provides a tokenized shell for text inputs with protocol add-ons, prefixes, suffixes, and inline actions.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <InputGroup>
9
- <InputGroupAddon>https://</InputGroupAddon>
10
- <InputGroupInput aria-label="Workspace URL" />
11
- <InputGroupButton>Save</InputGroupButton>
12
- </InputGroup>
13
- ```
14
-
15
- | Part | Purpose |
16
- | --- | --- |
17
- | `InputGroup` | shared input shell |
18
- | `InputGroupAddon` | prefix or suffix content |
19
- | `InputGroupInput` | native input |
20
- | `InputGroupButton` | inline action |
21
-
22
- | Prop | Values |
23
- | --- | --- |
24
- | `size` | `md`, `lg` |
25
- | `variant` | `default`, `soft` |
26
- | `state` | `default`, `error` |
27
-
28
- ## Token Contract
29
-
30
- Input Group reuses Banhaten input width, height, radius, border, shadow, typography, and focus tokens.
31
-
32
- ## RTL
33
-
34
- Use logical add-on order. Border placement uses logical inline sides.
35
-
36
- ## Accessibility
37
-
38
- Give `InputGroupInput` an accessible label through `aria-label`, `aria-labelledby`, or a surrounding Field.
39
-
40
- ## Install
41
-
42
- ```bash
43
- npx banhaten add input-group
44
- ```
45
-
46
- ## Examples
47
-
48
- Primary registry example: `examples/input-group-demo.tsx`.
49
-
50
- Open the live component page or run `npx banhaten docs input-group` to inspect source files, install command, and examples.
51
-
52
- ## RTL Rules
53
-
54
- - `inheritsDirection`: true
55
- - `spacing`: Add-ons and input segments use logical borders and inherited direction.
56
- - `textDirection`: Input text uses text-start so mixed Arabic and English values align naturally.
57
-
1
+ # Input Group
2
+
3
+ Input Group provides a tokenized shell for text inputs with protocol add-ons, prefixes, suffixes, and inline actions.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <InputGroup>
9
+ <InputGroupAddon>https://</InputGroupAddon>
10
+ <InputGroupInput aria-label="Workspace URL" />
11
+ <InputGroupButton>Save</InputGroupButton>
12
+ </InputGroup>
13
+ ```
14
+
15
+ | Part | Purpose |
16
+ | --- | --- |
17
+ | `InputGroup` | shared input shell |
18
+ | `InputGroupAddon` | prefix or suffix content |
19
+ | `InputGroupInput` | native input |
20
+ | `InputGroupButton` | inline action |
21
+
22
+ | Prop | Values |
23
+ | --- | --- |
24
+ | `size` | `md`, `lg` |
25
+ | `variant` | `default`, `soft` |
26
+ | `state` | `default`, `error` |
27
+
28
+ ## Token Contract
29
+
30
+ Input Group reuses Banhaten input width, height, radius, border, shadow, typography, and focus tokens.
31
+
32
+ ## RTL
33
+
34
+ Use logical add-on order. Border placement uses logical inline sides.
35
+
36
+ ## Accessibility
37
+
38
+ Give `InputGroupInput` an accessible label through `aria-label`, `aria-labelledby`, or a surrounding Field.
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ npx banhaten add input-group
44
+ ```
45
+
46
+ ## Examples
47
+
48
+ Primary registry example: `examples/input-group-demo.tsx`.
49
+
50
+ Open the live component page or run `npx banhaten docs input-group` to inspect source files, install command, and examples.
51
+
52
+ ## RTL Rules
53
+
54
+ - `inheritsDirection`: true
55
+ - `spacing`: Add-ons and input segments use logical borders and inherited direction.
56
+ - `textDirection`: Input text uses text-start so mixed Arabic and English values align naturally.
57
+
58
58
  <!-- registry-contract:start -->
59
59
  ## Registry Contract
60
60
 
@@ -1,59 +1,59 @@
1
- # Input OTP
2
-
3
- Input OTP captures one-time passcodes and short verification codes. It reuses the Banhaten Input surface and typography while adding grouped slots, paste distribution, hidden form value, masking, custom length, and RTL-aware keyboard navigation.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <InputOTP
9
- label="Verification code"
10
- length={6}
11
- name="code"
12
- onValueChange={setCode}
13
- />
14
- ```
15
-
16
- | Prop | Values |
17
- | --- | --- |
18
- | `value`, `defaultValue` | controlled or uncontrolled string |
19
- | `length` | slot count |
20
- | `groupPattern` | array of slot group sizes |
21
- | `masked` | `boolean` |
22
- | `variant` | `default`, `soft` |
23
- | `size` | `md`, `lg` |
24
- | `state` | `default`, `filled`, `error`, `disabled` |
25
-
26
- ## Token Contract
27
-
28
- Input OTP uses Input field tokens for surfaces, typography, focus, border, error, helper text, labels, slot gaps, and disabled states.
29
-
30
- ## RTL
31
-
32
- Slot groups inherit direction. Arrow navigation mirrors in RTL so visual previous and next follow the rendered direction.
33
-
34
- ## Accessibility
35
-
36
- Provide a clear label and helper text describing how many digits are expected. The hidden form value lets the component participate in standard form submission.
37
-
38
- ## Install
39
-
40
- ```bash
41
- npx banhaten add input-otp
42
- ```
43
-
44
- ## Examples
45
-
46
- Primary registry example: `examples/input-otp-demo.tsx`.
47
-
48
- Open the live component page or run `npx banhaten docs input-otp` to inspect source files, install command, and examples.
49
-
50
- ## RTL Rules
51
-
52
- - `inheritsDirection`: true
53
- - `keyboard`: Arrow navigation mirrors for RTL: visual previous and next follow the inherited direction.
54
- - `spacing`: Slot groups, separators, labels, and helper text use inherited direction plus Input spacing tokens.
55
- - `composition`: Each slot reuses the Banhaten Input surface and control typography instead of a separate field style.
56
-
1
+ # Input OTP
2
+
3
+ Input OTP captures one-time passcodes and short verification codes. It reuses the Banhaten Input surface and typography while adding grouped slots, paste distribution, hidden form value, masking, custom length, and RTL-aware keyboard navigation.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <InputOTP
9
+ label="Verification code"
10
+ length={6}
11
+ name="code"
12
+ onValueChange={setCode}
13
+ />
14
+ ```
15
+
16
+ | Prop | Values |
17
+ | --- | --- |
18
+ | `value`, `defaultValue` | controlled or uncontrolled string |
19
+ | `length` | slot count |
20
+ | `groupPattern` | array of slot group sizes |
21
+ | `masked` | `boolean` |
22
+ | `variant` | `default`, `soft` |
23
+ | `size` | `md`, `lg` |
24
+ | `state` | `default`, `filled`, `error`, `disabled` |
25
+
26
+ ## Token Contract
27
+
28
+ Input OTP uses Input field tokens for surfaces, typography, focus, border, error, helper text, labels, slot gaps, and disabled states.
29
+
30
+ ## RTL
31
+
32
+ Slot groups inherit direction. Arrow navigation mirrors in RTL so visual previous and next follow the rendered direction.
33
+
34
+ ## Accessibility
35
+
36
+ Provide a clear label and helper text describing how many digits are expected. The hidden form value lets the component participate in standard form submission.
37
+
38
+ ## Install
39
+
40
+ ```bash
41
+ npx banhaten add input-otp
42
+ ```
43
+
44
+ ## Examples
45
+
46
+ Primary registry example: `examples/input-otp-demo.tsx`.
47
+
48
+ Open the live component page or run `npx banhaten docs input-otp` to inspect source files, install command, and examples.
49
+
50
+ ## RTL Rules
51
+
52
+ - `inheritsDirection`: true
53
+ - `keyboard`: Arrow navigation mirrors for RTL: visual previous and next follow the inherited direction.
54
+ - `spacing`: Slot groups, separators, labels, and helper text use inherited direction plus Input spacing tokens.
55
+ - `composition`: Each slot reuses the Banhaten Input surface and control typography instead of a separate field style.
56
+
57
57
  <!-- registry-contract:start -->
58
58
  ## Registry Contract
59
59
 
@@ -1,111 +1,113 @@
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
-
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
+ Input is `320px` wide by default (`--bh-input-width`), the width of the library Input frame. In a form grid or form card, make each field fill its column: pass `className="w-full"`, or set `--bh-input-width: 100%` on the field. Keep the default for a field that stands on its own.
79
+
80
+ ## Token Contract
81
+
82
+ Input consumes Banhaten field, control, typography, spacing, border, radius, content, disabled, error, and focus tokens. Its default size is `lg` (36px). The `md` and `lg` sizes follow the library Input frame: the field content is padded `8px`, and the value starts `4px` further in when nothing precedes it. So text starts `12px` from the edge, text after a leading icon at `34px`, and trailing icons sit `8px` from the edge. The `comfortable` size keeps `12px` padding. Shortcut Inputs use the same 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.
83
+
84
+ ## RTL
85
+
86
+ 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.
87
+
88
+ ## Accessibility
89
+
90
+ 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.
91
+
92
+ ## Install
93
+
94
+ ```bash
95
+ npx banhaten add input
96
+ ```
97
+
98
+ ## Examples
99
+
100
+ Primary registry example: `examples/input-demo.tsx`.
101
+ Controlled quantity and action example: `examples/input-actions-demo.tsx`.
102
+
103
+ Open the live component page or run `npx banhaten docs input` to inspect source files, install command, and examples.
104
+
105
+ ## RTL Rules
106
+
107
+ - `inheritsDirection`: true
108
+ - `textAlignment`: Uses text-start and dir="auto" so Arabic and English labels, values, add-ons, tags, and helper text align naturally.
109
+ - `spacing`: Uses logical start/end borders and inherited direction so leading and trailing segments mirror in RTL.
110
+
109
111
  <!-- registry-contract:start -->
110
112
  ## Registry Contract
111
113
 
@@ -135,6 +137,6 @@ This table is generated from `registry/index.json`; edit the component-owned sou
135
137
  | `kinds` | `default`, `shortcut`, `add-on`, `inline-add-on`, `tags`, `inline-tags`, `trailing-dropdown`, `leading-dropdown`, `quantity`, `quantity-2`, `trailing-button`, `leading-button` |
136
138
  | `sizes` | `md`, `lg`, `comfortable` |
137
139
  | `states` | `default`, `filled`, `error`, `disabled` |
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` |
140
+ | `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-content-padding-x`, `--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-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-value-inset`, `--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` |
139
141
  | `variants` | `default`, `soft` |
140
142
  <!-- registry-contract:end -->
@@ -1,61 +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
- 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
-
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
+
59
59
  <!-- registry-contract:start -->
60
60
  ## Registry Contract
61
61