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,100 +1,100 @@
1
- # Button Group
2
-
3
- Button Group is a connected set of related button actions. It supports text buttons and icon-only buttons, three sizes, inherited LTR/RTL direction, logical dividers, and tokenized interaction states.
4
-
5
- The implementation follows the Figma component at `Design system 3.0 Copy / Button Group Item 1.2` (`390:12399`).
6
-
7
- ## API
8
-
9
- Use `ButtonGroup` as the connected container and `ButtonGroupItem` for each action.
10
-
11
- ```tsx
12
- <ButtonGroup aria-label="View options" size="md">
13
- <ButtonGroupItem>
14
- <PlusIcon data-icon="inline-start" />
15
- Button
16
- <PlusIcon data-icon="inline-end" />
17
- </ButtonGroupItem>
18
- <ButtonGroupItem aria-pressed>
19
- <PlusIcon data-icon="inline-start" />
20
- Active
21
- <PlusIcon data-icon="inline-end" />
22
- </ButtonGroupItem>
23
- </ButtonGroup>
24
- ```
25
-
26
- Use `ToggleGroup` when the connected controls own a single or multiple pressed-value model. It includes controlled and uncontrolled state plus Home, End, and direction-aware arrow-key focus movement.
27
-
28
- ```tsx
29
- <ToggleGroup aria-label="Text alignment" defaultValue="start">
30
- <ToggleGroupItem value="start">Start</ToggleGroupItem>
31
- <ToggleGroupItem value="center">Center</ToggleGroupItem>
32
- <ToggleGroupItem value="end">End</ToggleGroupItem>
33
- </ToggleGroup>
34
- ```
35
-
36
- ## Variants
37
-
38
- | Prop | Values |
39
- | --- | --- |
40
- | `size` | `md`, `sm`, `xs` |
41
- | `mode` | `default`, `iconOnly` |
42
- | `ButtonGroupItem aria-pressed` | `true`, `false` |
43
- | `ButtonGroupItem disabled` | `boolean` |
44
- | `ToggleGroup type` | `single`, `multiple` |
45
- | `ToggleGroup value`, `defaultValue` | `string`, `string[]` |
46
- | `ToggleGroupItem value` | `string` |
47
-
48
- Interaction styling is applied through native CSS pseudo states: `:hover`, `:active`, `:focus-visible`, `:disabled`, and `aria-pressed="true"`.
49
-
50
- ## States
51
-
52
- | State | Background | Content |
53
- | --- | --- | --- |
54
- | Default | `--bh-button-group-item-bg` | `--bh-button-group-content-default` |
55
- | Hover | `--bh-button-group-item-hover-bg` | `--bh-button-group-content-default` |
56
- | Pressed | `--bh-button-group-item-pressed-bg` | `--bh-button-group-content-default` |
57
- | Active | `--bh-button-group-item-active-bg` | `--bh-button-group-content-active` |
58
- | Disabled | `--bh-button-group-item-disabled-bg` | `--bh-button-group-content-disabled` |
59
-
60
- ## Dimensions
61
-
62
- | Size | Height | LTR text item | RTL text item | Icon-only item |
63
- | --- | ---: | ---: | ---: | ---: |
64
- | `md` | 40px | 128px | 124px | 40px |
65
- | `sm` | 36px | 120px | 116px | 36px |
66
- | `xs` | 32px | 112px | 108px | 32px |
67
-
68
- Text buttons use the design-system button typography tokens. Icon-only buttons require an accessible label.
69
-
70
- ## Install
71
-
72
- ```bash
73
- npx banhaten add button-group
74
- ```
75
-
76
- ## Examples
77
-
78
- Primary registry example: `examples/button-group-demo.tsx`.
79
-
80
- Open the live component page or run `npx banhaten docs button-group` to inspect source files, install command, and examples.
81
-
82
- ## Token Contract
83
-
84
- Component styles must resolve through Banhaten semantic tokens, component aliases, or documented exception-ledger values.
85
- Do not add raw colors, pixel values, opacity utilities, z-index values, durations, or shadow literals directly to component source.
86
- Covered source files: `components/button-group.tsx`.
87
-
88
- ## RTL Rules
89
-
90
- - `inheritsDirection`: true
91
- - `itemSizing`: LTR and RTL default items keep their fixed Figma matrix widths. Icon-only groups keep the same square dimensions.
92
- - `spacing`: Uses logical dividers and inherited flex direction so item order, icon order, padding, and separators follow LTR or RTL.
93
-
94
- ## Accessibility
95
-
96
- This component relies on `@radix-ui/react-slot` for its base accessibility behavior. Keep required labels, titles, descriptions, and focusable trigger/content relationships intact when composing it.
97
-
1
+ # Button Group
2
+
3
+ Button Group is a connected set of related button actions. It supports text buttons and icon-only buttons, three sizes, inherited LTR/RTL direction, logical dividers, and tokenized interaction states.
4
+
5
+ The implementation follows the Figma component at `Design system 3.0 Copy / Button Group Item 1.2` (`390:12399`).
6
+
7
+ ## API
8
+
9
+ Use `ButtonGroup` as the connected container and `ButtonGroupItem` for each action.
10
+
11
+ ```tsx
12
+ <ButtonGroup aria-label="View options" size="md">
13
+ <ButtonGroupItem>
14
+ <PlusIcon data-icon="inline-start" />
15
+ Button
16
+ <PlusIcon data-icon="inline-end" />
17
+ </ButtonGroupItem>
18
+ <ButtonGroupItem aria-pressed>
19
+ <PlusIcon data-icon="inline-start" />
20
+ Active
21
+ <PlusIcon data-icon="inline-end" />
22
+ </ButtonGroupItem>
23
+ </ButtonGroup>
24
+ ```
25
+
26
+ Use `ToggleGroup` when the connected controls own a single or multiple pressed-value model. It includes controlled and uncontrolled state plus Home, End, and direction-aware arrow-key focus movement.
27
+
28
+ ```tsx
29
+ <ToggleGroup aria-label="Text alignment" defaultValue="start">
30
+ <ToggleGroupItem value="start">Start</ToggleGroupItem>
31
+ <ToggleGroupItem value="center">Center</ToggleGroupItem>
32
+ <ToggleGroupItem value="end">End</ToggleGroupItem>
33
+ </ToggleGroup>
34
+ ```
35
+
36
+ ## Variants
37
+
38
+ | Prop | Values |
39
+ | --- | --- |
40
+ | `size` | `md`, `sm`, `xs` |
41
+ | `mode` | `default`, `iconOnly` |
42
+ | `ButtonGroupItem aria-pressed` | `true`, `false` |
43
+ | `ButtonGroupItem disabled` | `boolean` |
44
+ | `ToggleGroup type` | `single`, `multiple` |
45
+ | `ToggleGroup value`, `defaultValue` | `string`, `string[]` |
46
+ | `ToggleGroupItem value` | `string` |
47
+
48
+ Interaction styling is applied through native CSS pseudo states: `:hover`, `:active`, `:focus-visible`, `:disabled`, and `aria-pressed="true"`.
49
+
50
+ ## States
51
+
52
+ | State | Background | Content |
53
+ | --- | --- | --- |
54
+ | Default | `--bh-button-group-item-bg` | `--bh-button-group-content-default` |
55
+ | Hover | `--bh-button-group-item-hover-bg` | `--bh-button-group-content-default` |
56
+ | Pressed | `--bh-button-group-item-pressed-bg` | `--bh-button-group-content-default` |
57
+ | Active | `--bh-button-group-item-active-bg` | `--bh-button-group-content-active` |
58
+ | Disabled | `--bh-button-group-item-disabled-bg` | `--bh-button-group-content-disabled` |
59
+
60
+ ## Dimensions
61
+
62
+ | Size | Height | LTR text item | RTL text item | Icon-only item |
63
+ | --- | ---: | ---: | ---: | ---: |
64
+ | `md` | 40px | 128px | 124px | 40px |
65
+ | `sm` | 36px | 120px | 116px | 36px |
66
+ | `xs` | 32px | 112px | 108px | 32px |
67
+
68
+ Text buttons use the design-system button typography tokens. Default glyphs are 18px inside preserved 20px slots. Icon-only buttons require an accessible label.
69
+
70
+ ## Install
71
+
72
+ ```bash
73
+ npx banhaten add button-group
74
+ ```
75
+
76
+ ## Examples
77
+
78
+ Primary registry example: `examples/button-group-demo.tsx`.
79
+
80
+ Open the live component page or run `npx banhaten docs button-group` to inspect source files, install command, and examples.
81
+
82
+ ## Token Contract
83
+
84
+ Component styles must resolve through Banhaten semantic tokens, component aliases, or documented exception-ledger values.
85
+ Do not add raw colors, pixel values, opacity utilities, z-index values, durations, or shadow literals directly to component source.
86
+ Covered source files: `components/button-group.tsx`.
87
+
88
+ ## RTL Rules
89
+
90
+ - `inheritsDirection`: true
91
+ - `itemSizing`: LTR and RTL default items keep their fixed Figma matrix widths. Icon-only groups keep the same square dimensions.
92
+ - `spacing`: Uses logical dividers and inherited flex direction so item order, icon order, padding, and separators follow LTR or RTL.
93
+
94
+ ## Accessibility
95
+
96
+ This component relies on `@radix-ui/react-slot` for its base accessibility behavior. Keep required labels, titles, descriptions, and focusable trigger/content relationships intact when composing it.
97
+
98
98
  <!-- registry-contract:start -->
99
99
  ## Registry Contract
100
100
 
@@ -113,6 +113,6 @@ This table is generated from `registry/index.json`; edit the component-owned sou
113
113
  | `modes` | `default`, `iconOnly` |
114
114
  | `selectionTypes` | `single`, `multiple` |
115
115
  | `sizes` | `md`, `sm`, `xs` |
116
- | `tokens` | `--bh-border-width-default`, `--bh-button-group-bg`, `--bh-button-group-border`, `--bh-button-group-content`, `--bh-button-group-content-active`, `--bh-button-group-content-disabled`, `--bh-button-group-divider`, `--bh-button-group-icon-size`, `--bh-button-group-item-active-bg`, `--bh-button-group-item-bg`, `--bh-button-group-item-disabled-bg`, `--bh-button-group-item-hover-bg`, `--bh-button-group-item-pressed-bg`, `--bh-button-group-label-padding-x`, `--bh-button-group-md-gap`, `--bh-button-group-md-height`, `--bh-button-group-md-icon-padding-x`, `--bh-button-group-md-item-rtl-width`, `--bh-button-group-md-item-width`, `--bh-button-group-md-padding-x`, `--bh-button-group-radius`, `--bh-button-group-sm-gap`, `--bh-button-group-sm-height`, `--bh-button-group-sm-icon-padding-x`, `--bh-button-group-sm-item-rtl-width`, `--bh-button-group-sm-item-width`, `--bh-button-group-sm-padding-x`, `--bh-button-group-xs-gap`, `--bh-button-group-xs-height`, `--bh-button-group-xs-icon-padding-x`, `--bh-button-group-xs-item-rtl-width`, `--bh-button-group-xs-item-width`, `--bh-button-group-xs-padding-x`, `--bh-text-button-font-size`, `--bh-text-button-font-weight`, `--bh-text-button-letter-spacing`, `--bh-text-button-line-height`, `--bh-z-raised`, `--shadow-button-group`, `--shadow-button-group-focus`, `--shadow-component-default` |
116
+ | `tokens` | `--bh-border-width-default`, `--bh-button-group-bg`, `--bh-button-group-border`, `--bh-button-group-content`, `--bh-button-group-content-active`, `--bh-button-group-content-disabled`, `--bh-button-group-divider`, `--bh-button-group-icon-size`, `--bh-button-group-icon-slot-size`, `--bh-button-group-item-active-bg`, `--bh-button-group-item-bg`, `--bh-button-group-item-disabled-bg`, `--bh-button-group-item-hover-bg`, `--bh-button-group-item-pressed-bg`, `--bh-button-group-label-padding-x`, `--bh-button-group-md-gap`, `--bh-button-group-md-height`, `--bh-button-group-md-icon-padding-x`, `--bh-button-group-md-item-rtl-width`, `--bh-button-group-md-item-width`, `--bh-button-group-md-padding-x`, `--bh-button-group-radius`, `--bh-button-group-sm-gap`, `--bh-button-group-sm-height`, `--bh-button-group-sm-icon-padding-x`, `--bh-button-group-sm-item-rtl-width`, `--bh-button-group-sm-item-width`, `--bh-button-group-sm-padding-x`, `--bh-button-group-xs-gap`, `--bh-button-group-xs-height`, `--bh-button-group-xs-icon-padding-x`, `--bh-button-group-xs-item-rtl-width`, `--bh-button-group-xs-item-width`, `--bh-button-group-xs-padding-x`, `--bh-text-button-font-size`, `--bh-text-button-font-weight`, `--bh-text-button-letter-spacing`, `--bh-text-button-line-height`, `--bh-z-raised`, `--elevation-button-group`, `--elevation-button-group-focus`, `--elevation-component-default` |
117
117
  | `widths` | `fixed`, `content` |
118
118
  <!-- registry-contract:end -->
@@ -1,81 +1,83 @@
1
- # Button
2
-
3
- Button is the primary action primitive for forms, workflows, navigation actions, and destructive confirmations. It supports semantic variants, text and icon sizes, loading composition, link composition through `asChild`, and RTL-safe icon behavior.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <Button variant="default" size="default">
9
- Save changes
10
- </Button>
11
- ```
12
-
13
- | Prop | Values | Default |
14
- | --- | --- | --- |
15
- | `variant` | `default`, `secondary`, `soft`, `outline`, `ghost`, `ghost-primary`, `danger`, `soft-danger`, `white` | `default` |
16
- | `size` | `xs`, `sm`, `default`, `lg`, `xl`, `icon-xs`, `icon-sm`, `icon`, `icon-lg`, `icon-xl` | `default` |
17
- | `asChild` | `boolean` | `false` |
18
- | `disabled` | `boolean` | `false` |
19
- | `aria-busy` | `boolean` | none |
20
-
21
- ## Examples
22
-
23
- ```tsx
24
- <Button>
25
- <PlusIcon data-icon="inline-start" />
26
- New item
27
- </Button>
28
-
29
- <Button variant="outline">
30
- Continue
31
- <ArrowRightIcon data-icon="inline-end" data-rtl-flip="true" />
32
- </Button>
33
-
34
- <Button disabled aria-busy="true">
35
- <Spinner data-icon="inline-start" />
36
- Loading
37
- </Button>
38
- ```
39
-
40
- ```tsx
41
- <div dir="rtl">
42
- <Button>إرسال</Button>
43
- <Button variant="outline">
44
- متابعة
45
- <ArrowRightIcon data-icon="inline-end" data-rtl-flip="true" />
46
- </Button>
47
- </div>
48
- ```
49
-
50
- ## Token Contract
51
-
52
- Button consumes semantic interaction, content, border, radius, typography, spacing, opacity, and shadow tokens. Component source should not hard-code Figma color, spacing, radius, or shadow literals.
53
-
54
- - Typography: `--bh-text-button-font-size`, `--bh-text-button-line-height`, `--bh-text-button-font-weight`, `--bh-text-button-letter-spacing`
55
- - Shape: `--bh-control-default`
56
- - Heights and padding: `--bh-button-*-height`, `--bh-button-*-padding-x`, `--bh-button-*-padding-y`
57
- - Icon rhythm: `--bh-button-icon-size`, `--bh-button-icon-offset`, `--bh-button-label-padding-x`
58
- - Effects: `--shadow-button-raised`, `--shadow-button-secondary`, `--shadow-button-soft`, `--shadow-button-focus`, `--shadow-button-danger-focus`
59
-
60
- ## RTL Rules
61
-
62
- - Button inherits `dir` from the nearest parent.
63
- - Text labels render with `dir="auto"` so Arabic and English labels resolve naturally.
64
- - Use `data-icon="inline-start"` and `data-icon="inline-end"` for optical icon offsets.
65
- - Use `data-rtl-flip="true"` only for directional icons that should mirror, such as arrows and chevrons.
66
-
67
- ## Accessibility
68
-
69
- - Use native `type`, `disabled`, and `aria-busy` attributes for behavior.
70
- - Icon-only buttons must have an accessible name through `aria-label`.
71
- - Use `asChild` for anchors or router links instead of nesting interactive elements.
72
-
73
- ## Install
74
-
75
- ```bash
76
- npx banhaten add button
77
- ```
78
-
1
+ # Button
2
+
3
+ Button is the primary action primitive for forms, workflows, navigation actions, and destructive confirmations. It supports semantic variants, text and icon sizes, loading composition, link composition through `asChild`, and RTL-safe icon behavior.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <Button variant="default" size="default">
9
+ Save changes
10
+ </Button>
11
+ ```
12
+
13
+ | Prop | Values | Default |
14
+ | --- | --- | --- |
15
+ | `variant` | `default`, `secondary`, `soft`, `outline`, `ghost`, `ghost-primary`, `danger`, `soft-danger`, `white`, `success`, `warning`, `link` | `default` |
16
+ | `size` | `xs`, `sm`, `default`, `lg`, `xl`, `icon-xs`, `icon-sm`, `icon`, `icon-lg`, `icon-xl` | `default` |
17
+ | `asChild` | `boolean` | `false` |
18
+ | `disabled` | `boolean` | `false` |
19
+ | `aria-busy` | `boolean` | none |
20
+
21
+ `destructive` and `soft-destructive` remain accepted as deprecated compatibility aliases. Replace them with `danger` and `soft-danger`, respectively; the aliases are not separate visual treatments and will remain available for the repository's documented deprecation window.
22
+
23
+ ## Examples
24
+
25
+ ```tsx
26
+ <Button>
27
+ <PlusIcon data-icon="inline-start" />
28
+ New item
29
+ </Button>
30
+
31
+ <Button variant="outline">
32
+ Continue
33
+ <ArrowRightIcon data-icon="inline-end" data-rtl-flip="true" />
34
+ </Button>
35
+
36
+ <Button disabled aria-busy="true">
37
+ <Spinner data-icon="inline-start" />
38
+ Loading
39
+ </Button>
40
+ ```
41
+
42
+ ```tsx
43
+ <div dir="rtl">
44
+ <Button>إرسال</Button>
45
+ <Button variant="outline">
46
+ متابعة
47
+ <ArrowRightIcon data-icon="inline-end" data-rtl-flip="true" />
48
+ </Button>
49
+ </div>
50
+ ```
51
+
52
+ ## Token Contract
53
+
54
+ Button consumes semantic interaction, content, border, radius, typography, spacing, opacity, and elevation tokens. Component source should not hard-code Figma color, spacing, radius, or elevation recipes.
55
+
56
+ - Typography: `--bh-text-button-font-size`, `--bh-text-button-line-height`, `--bh-text-button-font-weight`, `--bh-text-button-letter-spacing`
57
+ - Shape: `--bh-control-default`
58
+ - Heights and padding: `--bh-button-*-height`, `--bh-button-*-padding-x`, `--bh-button-*-padding-y`
59
+ - Icon rhythm: `--bh-button-icon-size` is an 18px glyph inside `--bh-button-icon-slot-size` at 20px; `--bh-button-icon-offset` and `--bh-button-label-padding-x` preserve optical alignment.
60
+ - Effects: `--elevation-button-raised`, `--elevation-button-secondary`, `--elevation-button-soft`, `--elevation-button-focus`, `--elevation-button-danger-focus`
61
+
62
+ ## RTL Rules
63
+
64
+ - Button inherits `dir` from the nearest parent.
65
+ - Text labels render with `dir="auto"` so Arabic and English labels resolve naturally.
66
+ - Use `data-icon="inline-start"` and `data-icon="inline-end"` for optical icon offsets.
67
+ - Use `data-rtl-flip="true"` only for directional icons that should mirror, such as arrows and chevrons.
68
+
69
+ ## Accessibility
70
+
71
+ - Use native `type`, `disabled`, and `aria-busy` attributes for behavior.
72
+ - Icon-only buttons must have an accessible name through `aria-label`.
73
+ - Use `asChild` for anchors or router links instead of nesting interactive elements.
74
+
75
+ ## Install
76
+
77
+ ```bash
78
+ npx banhaten add button
79
+ ```
80
+
79
81
  <!-- registry-contract:start -->
80
82
  ## Registry Contract
81
83
 
@@ -87,9 +89,10 @@ This table is generated from `registry/index.json`; edit the component-owned sou
87
89
  | `supportedExports` | `components/button.tsx: Button, buttonVariants` |
88
90
  | `parts` | `Button` |
89
91
  | `registryDependencies` | `spinner` |
92
+ | `props.variant` | `"default" \| "secondary" \| "soft" \| "outline" \| "ghost" \| "ghost-primary" \| "danger" \| "soft-danger" \| "white" \| "success" \| "warning" \| "link" \| "destructive" \| "soft-destructive"; default "default"; Twelve canonical semantic treatments. The deprecated destructive and soft-destructive compatibility aliases remain accepted and map to danger and soft-danger, respectively.` |
90
93
  | `props.density` | `"compact" \| "default" \| "comfortable"; default "comfortable"; Preferred cross-component sizing contract. Maps to legacy xs, sm, or default sizes while preserving icon-only sizing.` |
91
94
  | `densities` | `compact`, `default`, `comfortable` |
92
95
  | `sizes` | `xs`, `sm`, `default`, `lg`, `xl`, `icon-xs`, `icon-sm`, `icon`, `icon-lg`, `icon-xl` |
93
- | `tokens` | `--bh-bg-always-white`, `--bh-border-brand-strong`, `--bh-border-danger-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-focus`, `--bh-border-width-default`, `--bh-button-gap`, `--bh-button-gap-xs`, `--bh-button-icon-offset`, `--bh-button-icon-size`, `--bh-button-label-padding-x`, `--bh-button-lg-height`, `--bh-button-lg-padding-x`, `--bh-button-lg-padding-y`, `--bh-button-md-height`, `--bh-button-md-padding-x`, `--bh-button-secondary-border`, `--bh-button-secondary-focus-border`, `--bh-button-sm-height`, `--bh-button-sm-padding-x`, `--bh-button-sm-padding-y`, `--bh-button-xl-height`, `--bh-button-xl-padding-y`, `--bh-button-xs-height`, `--bh-button-xs-padding-x`, `--bh-content-brand-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-on-brand`, `--bh-content-on-color`, `--bh-content-on-light`, `--bh-content-on-success`, `--bh-content-on-warning`, `--bh-control-default`, `--bh-interactive-brand-default`, `--bh-interactive-brand-disabled`, `--bh-interactive-brand-hover`, `--bh-interactive-brand-pressed`, `--bh-interactive-danger-default`, `--bh-interactive-danger-disabled`, `--bh-interactive-danger-hover`, `--bh-interactive-danger-pressed`, `--bh-interactive-danger-soft-default`, `--bh-interactive-danger-soft-disabled`, `--bh-interactive-danger-soft-hover`, `--bh-interactive-danger-soft-pressed`, `--bh-interactive-ghost-default`, `--bh-interactive-ghost-disabled`, `--bh-interactive-ghost-hover`, `--bh-interactive-ghost-pressed`, `--bh-interactive-outlined-default`, `--bh-interactive-outlined-disabled`, `--bh-interactive-outlined-hover`, `--bh-interactive-outlined-pressed`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-interactive-secondary-hover`, `--bh-interactive-secondary-pressed`, `--bh-interactive-soft-default`, `--bh-interactive-soft-disabled`, `--bh-interactive-soft-hover`, `--bh-interactive-soft-pressed`, `--bh-interactive-success-default`, `--bh-interactive-success-hover`, `--bh-interactive-success-pressed`, `--bh-interactive-warning-default`, `--bh-interactive-warning-hover`, `--bh-interactive-warning-pressed`, `--bh-opacity-30`, `--bh-space-none`, `--bh-text-button-font-size`, `--bh-text-button-font-weight`, `--bh-text-button-letter-spacing`, `--bh-text-button-line-height`, `--shadow-button-danger-focus`, `--shadow-button-focus`, `--shadow-button-raised`, `--shadow-button-secondary`, `--shadow-button-secondary-focus`, `--shadow-button-soft` |
94
- | `variants` | `default`, `secondary`, `soft`, `outline`, `ghost`, `ghost-primary`, `danger`, `soft-danger`, `white` |
96
+ | `tokens` | `--bh-bg-always-white`, `--bh-border-brand-strong`, `--bh-border-danger-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-focus`, `--bh-border-width-default`, `--bh-button-gap`, `--bh-button-gap-xs`, `--bh-button-icon-offset`, `--bh-button-icon-size`, `--bh-button-icon-slot-size`, `--bh-button-label-padding-x`, `--bh-button-lg-height`, `--bh-button-lg-padding-x`, `--bh-button-lg-padding-y`, `--bh-button-md-height`, `--bh-button-md-padding-x`, `--bh-button-secondary-border`, `--bh-button-secondary-focus-border`, `--bh-button-sm-height`, `--bh-button-sm-padding-x`, `--bh-button-sm-padding-y`, `--bh-button-xl-height`, `--bh-button-xl-padding-y`, `--bh-button-xs-height`, `--bh-button-xs-padding-x`, `--bh-content-brand-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-on-brand`, `--bh-content-on-color`, `--bh-content-on-light`, `--bh-content-on-success`, `--bh-content-on-warning`, `--bh-control-default`, `--bh-interactive-brand-default`, `--bh-interactive-brand-disabled`, `--bh-interactive-brand-hover`, `--bh-interactive-brand-pressed`, `--bh-interactive-danger-default`, `--bh-interactive-danger-disabled`, `--bh-interactive-danger-hover`, `--bh-interactive-danger-pressed`, `--bh-interactive-danger-soft-default`, `--bh-interactive-danger-soft-disabled`, `--bh-interactive-danger-soft-hover`, `--bh-interactive-danger-soft-pressed`, `--bh-interactive-ghost-default`, `--bh-interactive-ghost-disabled`, `--bh-interactive-ghost-hover`, `--bh-interactive-ghost-pressed`, `--bh-interactive-outlined-default`, `--bh-interactive-outlined-disabled`, `--bh-interactive-outlined-hover`, `--bh-interactive-outlined-pressed`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-interactive-secondary-hover`, `--bh-interactive-secondary-pressed`, `--bh-interactive-soft-default`, `--bh-interactive-soft-disabled`, `--bh-interactive-soft-hover`, `--bh-interactive-soft-pressed`, `--bh-interactive-success-default`, `--bh-interactive-success-hover`, `--bh-interactive-success-pressed`, `--bh-interactive-warning-default`, `--bh-interactive-warning-hover`, `--bh-interactive-warning-pressed`, `--bh-opacity-30`, `--bh-space-none`, `--bh-text-button-font-size`, `--bh-text-button-font-weight`, `--bh-text-button-letter-spacing`, `--bh-text-button-line-height`, `--elevation-button-danger-focus`, `--elevation-button-focus`, `--elevation-button-raised`, `--elevation-button-secondary`, `--elevation-button-secondary-focus`, `--elevation-button-soft` |
97
+ | `variants` | `default`, `secondary`, `soft`, `outline`, `ghost`, `ghost-primary`, `danger`, `soft-danger`, `white`, `success`, `warning`, `link` |
95
98
  <!-- registry-contract:end -->
@@ -1,90 +1,90 @@
1
- # Card
2
-
3
- Card is a token-built surface primitive for product summaries, media tiles, and action panels. It supports vertical and horizontal layouts, leading and trailing image treatments, full-image cards, desktop/mobile spacing, footer actions, and RTL-safe text.
4
-
5
- Use `CardSurface` when a product-specific composition needs the owned Banhaten card surface while supplying its own internal layout.
6
-
7
- ```tsx
8
- <CardSurface>
9
- <h3>Custom metric content</h3>
10
- </CardSurface>
11
- ```
12
-
13
- ## Install
14
-
15
- ```bash
16
- npx banhaten add card
17
- ```
18
-
19
- ## Anatomy
20
-
21
- - `Card`: root surface with title, subtitle, description, media, and optional footer composition.
22
- - `CardMedia`: image/media slot with leading, trailing, or full-image treatment.
23
- - `CardFooter`: supporting metadata or action area.
24
- - `CardActions`: Button-composed primary and secondary actions.
25
-
26
- ## Example
27
-
28
- ```tsx
29
- import { Card } from "@/components/ui/card"
30
-
31
- export function Example() {
32
- return (
33
- <Card
34
- title="Project activity"
35
- subtitle="Updated 2 minutes ago"
36
- description="A compact summary of the latest workspace changes."
37
- orientation="horizontal"
38
- type="leading-image"
39
- />
40
- )
41
- }
42
- ```
43
-
44
- ## Variants
45
-
46
- | Prop | Values |
47
- | --- | --- |
48
- | `orientation` | `vertical`, `horizontal` |
49
- | `type` | `leading-image`, `trailing-image`, `full-image` |
50
- | `breakpoint` | `desktop`, `mobile` |
51
- | `dir` | inherited, `ltr`, `rtl` |
52
-
53
- ## RTL
54
-
55
- Card uses logical spacing, inherited direction, and `dir="auto"` copy wrappers so title, subtitle, description, footer actions, and menu affordances mirror naturally.
56
-
57
- ## API
58
-
59
- Supported runtime exports: `Card`, `CardActions`, `CardFooter`, `CardMedia`, `CardSurface`, `cardVariants`.
60
-
61
- | Contract | Values |
62
- | --- | --- |
63
- | `types` | `leading-image`, `trailing-image`, `full-image` |
64
- | `orientations` | `vertical`, `horizontal` |
65
-
66
- ## Examples
67
-
68
- Primary registry example: `examples/card-demo.tsx`.
69
-
70
- Open the live component page or run `npx banhaten docs card` to inspect source files, install command, and examples.
71
-
72
- ## Token Contract
73
-
74
- Component styles must resolve through Banhaten semantic tokens, component aliases, or documented exception-ledger values.
75
- Do not add raw colors, pixel values, opacity utilities, z-index values, durations, or shadow literals directly to component source.
76
- Covered source files: `components/card.tsx`, `assets/images/art-01.jpg`.
77
-
78
- ## RTL Rules
79
-
80
- - `inheritsDirection`: true
81
- - `spacing`: Uses logical direction, text-start behavior, and dir="auto" copy so title, subtitle, description, footer actions, and menu affordance mirror naturally.
82
- - `actions`: The default footer composes the existing Button primitive and keeps action order logical in LTR and RTL.
83
-
84
- ## Accessibility
85
-
86
- Keep native semantics, accessible names, keyboard reachability, focus-visible treatment, and status/error announcements intact when composing this component.
87
-
1
+ # Card
2
+
3
+ Card is a token-built surface primitive for product summaries, media tiles, and action panels. It supports vertical and horizontal layouts, leading and trailing image treatments, full-image cards, desktop/mobile spacing, footer actions, and RTL-safe text.
4
+
5
+ Use `CardSurface` when a product-specific composition needs the owned Banhaten card surface while supplying its own internal layout.
6
+
7
+ ```tsx
8
+ <CardSurface>
9
+ <h3>Custom metric content</h3>
10
+ </CardSurface>
11
+ ```
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npx banhaten add card
17
+ ```
18
+
19
+ ## Anatomy
20
+
21
+ - `Card`: root surface with title, subtitle, description, media, and optional footer composition.
22
+ - `CardMedia`: image/media slot with leading, trailing, or full-image treatment.
23
+ - `CardFooter`: supporting metadata or action area.
24
+ - `CardActions`: Button-composed primary and secondary actions.
25
+
26
+ ## Example
27
+
28
+ ```tsx
29
+ import { Card } from "@/components/ui/card"
30
+
31
+ export function Example() {
32
+ return (
33
+ <Card
34
+ title="Project activity"
35
+ subtitle="Updated 2 minutes ago"
36
+ description="A compact summary of the latest workspace changes."
37
+ orientation="horizontal"
38
+ type="leading-image"
39
+ />
40
+ )
41
+ }
42
+ ```
43
+
44
+ ## Variants
45
+
46
+ | Prop | Values |
47
+ | --- | --- |
48
+ | `orientation` | `vertical`, `horizontal` |
49
+ | `type` | `leading-image`, `trailing-image`, `full-image` |
50
+ | `breakpoint` | `desktop`, `mobile` |
51
+ | `dir` | inherited, `ltr`, `rtl` |
52
+
53
+ ## RTL
54
+
55
+ Card uses logical spacing, inherited direction, and `dir="auto"` copy wrappers so title, subtitle, description, footer actions, and menu affordances mirror naturally.
56
+
57
+ ## API
58
+
59
+ Supported runtime exports: `Card`, `CardActions`, `CardFooter`, `CardMedia`, `CardSurface`, `cardVariants`.
60
+
61
+ | Contract | Values |
62
+ | --- | --- |
63
+ | `types` | `leading-image`, `trailing-image`, `full-image` |
64
+ | `orientations` | `vertical`, `horizontal` |
65
+
66
+ ## Examples
67
+
68
+ Primary registry example: `examples/card-demo.tsx`.
69
+
70
+ Open the live component page or run `npx banhaten docs card` to inspect source files, install command, and examples.
71
+
72
+ ## Token Contract
73
+
74
+ Component styles must resolve through Banhaten semantic tokens, component aliases, or documented exception-ledger values.
75
+ Do not add raw colors, pixel values, opacity utilities, z-index values, durations, or shadow literals directly to component source.
76
+ Covered source files: `components/card.tsx`, `assets/images/art-01.jpg`.
77
+
78
+ ## RTL Rules
79
+
80
+ - `inheritsDirection`: true
81
+ - `spacing`: Uses logical direction, text-start behavior, and dir="auto" copy so title, subtitle, description, footer actions, and menu affordance mirror naturally.
82
+ - `actions`: The default footer composes the existing Button primitive and keeps action order logical in LTR and RTL.
83
+
84
+ ## Accessibility
85
+
86
+ Keep native semantics, accessible names, keyboard reachability, focus-visible treatment, and status/error announcements intact when composing this component.
87
+
88
88
  <!-- registry-contract:start -->
89
89
  ## Registry Contract
90
90
 
@@ -98,6 +98,6 @@ This table is generated from `registry/index.json`; edit the component-owned sou
98
98
  | `registryDependencies` | `button` |
99
99
  | `breakpoints` | `desktop`, `mobile` |
100
100
  | `orientations` | `vertical`, `horizontal` |
101
- | `tokens` | `--bh-bg-accent-green-subtle`, `--bh-bg-accent-sky-subtle`, `--bh-bg-neutral-subtle`, `--bh-bg-raised`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-card-actions-max-width`, `--bh-card-bg`, `--bh-card-border`, `--bh-card-content-padding`, `--bh-card-desktop-content-padding`, `--bh-card-desktop-full-height`, `--bh-card-desktop-horizontal-padding`, `--bh-card-desktop-media-height`, `--bh-card-full-height`, `--bh-card-horizontal-media-width`, `--bh-card-horizontal-min-height`, `--bh-card-horizontal-padding`, `--bh-card-horizontal-width`, `--bh-card-media-height`, `--bh-card-media-overlay`, `--bh-card-mobile-content-padding`, `--bh-card-mobile-full-height`, `--bh-card-mobile-horizontal-padding`, `--bh-card-mobile-media-height`, `--bh-card-more-icon-size`, `--bh-card-more-size`, `--bh-card-radius`, `--bh-card-vertical-width`, `--bh-content-default`, `--bh-content-on-color`, `--bh-content-subtle`, `--bh-control-default`, `--bh-interactive-ghost-hover`, `--bh-radius-3xl-16`, `--bh-space-3xl-16`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-md-8`, `--bh-space-xl-12`, `--bh-space-xxs-2`, `--bh-text-body-lg-regular-font-size`, `--bh-text-body-lg-regular-font-weight`, `--bh-text-body-lg-regular-letter-spacing`, `--bh-text-body-lg-regular-line-height`, `--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-heading-sm-semibold-font-size`, `--bh-text-heading-sm-semibold-font-weight`, `--bh-text-heading-sm-semibold-letter-spacing`, `--bh-text-heading-sm-semibold-line-height`, `--shadow-button-focus` |
101
+ | `tokens` | `--bh-bg-accent-green-subtle`, `--bh-bg-accent-sky-subtle`, `--bh-bg-neutral-subtle`, `--bh-bg-raised`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-card-actions-max-width`, `--bh-card-bg`, `--bh-card-border`, `--bh-card-content-padding`, `--bh-card-desktop-content-padding`, `--bh-card-desktop-full-height`, `--bh-card-desktop-horizontal-padding`, `--bh-card-desktop-media-height`, `--bh-card-full-height`, `--bh-card-horizontal-media-width`, `--bh-card-horizontal-min-height`, `--bh-card-horizontal-padding`, `--bh-card-horizontal-width`, `--bh-card-media-height`, `--bh-card-media-overlay`, `--bh-card-mobile-content-padding`, `--bh-card-mobile-full-height`, `--bh-card-mobile-horizontal-padding`, `--bh-card-mobile-media-height`, `--bh-card-more-icon-size`, `--bh-card-more-size`, `--bh-card-radius`, `--bh-card-vertical-width`, `--bh-content-default`, `--bh-content-on-color`, `--bh-content-subtle`, `--bh-control-default`, `--bh-interactive-ghost-hover`, `--bh-radius-3xl-16`, `--bh-space-3xl-16`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-md-8`, `--bh-space-xl-12`, `--bh-space-xxs-2`, `--bh-text-body-lg-regular-font-size`, `--bh-text-body-lg-regular-font-weight`, `--bh-text-body-lg-regular-letter-spacing`, `--bh-text-body-lg-regular-line-height`, `--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-heading-sm-semibold-font-size`, `--bh-text-heading-sm-semibold-font-weight`, `--bh-text-heading-sm-semibold-letter-spacing`, `--bh-text-heading-sm-semibold-line-height`, `--elevation-button-focus` |
102
102
  | `types` | `leading-image`, `trailing-image`, `full-image` |
103
103
  <!-- registry-contract:end -->