banhaten 0.1.3 → 0.3.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 (275) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/CONTRIBUTING.md +44 -0
  3. package/README.md +65 -13
  4. package/SECURITY.md +15 -0
  5. package/banhaten.config.example.json +0 -2
  6. package/docs/design-system/README.md +9 -0
  7. package/docs/design-system/adoption-quality-remediation.md +87 -0
  8. package/docs/design-system/agent-usage.md +13 -0
  9. package/docs/design-system/appearance-presets.md +6 -1
  10. package/docs/design-system/component-docs-pattern.md +81 -0
  11. package/docs/design-system/component-implementation-ownership-audit.md +244 -0
  12. package/docs/design-system/component-quality-audit-2026-08-20.md +223 -0
  13. package/docs/design-system/component-showcase-consistency-report.md +2 -0
  14. package/docs/design-system/component-token-consistency-audit.md +13 -3
  15. package/docs/design-system/components/README.md +4 -2
  16. package/docs/design-system/components/accordion.md +16 -0
  17. package/docs/design-system/components/activity-feed.md +17 -1
  18. package/docs/design-system/components/activity-heatmap.md +73 -0
  19. package/docs/design-system/components/alert-dialog.md +17 -0
  20. package/docs/design-system/components/alert.md +46 -14
  21. package/docs/design-system/components/aspect-ratio.md +15 -0
  22. package/docs/design-system/components/attribute.md +16 -0
  23. package/docs/design-system/components/autocomplete.md +19 -0
  24. package/docs/design-system/components/avatar.md +18 -0
  25. package/docs/design-system/components/badge.md +19 -0
  26. package/docs/design-system/components/banner.md +19 -1
  27. package/docs/design-system/components/breadcrumbs.md +17 -0
  28. package/docs/design-system/components/button-group.md +35 -0
  29. package/docs/design-system/components/button.md +18 -0
  30. package/docs/design-system/components/card.md +26 -1
  31. package/docs/design-system/components/carousel.md +20 -3
  32. package/docs/design-system/components/catalog-components.md +18 -1
  33. package/docs/design-system/components/chart.md +15 -0
  34. package/docs/design-system/components/checkbox.md +16 -0
  35. package/docs/design-system/components/collapsible.md +15 -0
  36. package/docs/design-system/components/command.md +15 -0
  37. package/docs/design-system/components/context-menu.md +15 -0
  38. package/docs/design-system/components/date-picker.md +21 -1
  39. package/docs/design-system/components/divider.md +16 -0
  40. package/docs/design-system/components/empty-state.md +17 -0
  41. package/docs/design-system/components/field.md +17 -0
  42. package/docs/design-system/components/file-upload.md +18 -0
  43. package/docs/design-system/components/hover-card.md +15 -0
  44. package/docs/design-system/components/input-group.md +17 -0
  45. package/docs/design-system/components/input-otp.md +18 -0
  46. package/docs/design-system/components/input.md +43 -7
  47. package/docs/design-system/components/item.md +72 -0
  48. package/docs/design-system/components/kbd.md +18 -0
  49. package/docs/design-system/components/label.md +16 -0
  50. package/docs/design-system/components/menu.md +17 -0
  51. package/docs/design-system/components/menubar.md +15 -0
  52. package/docs/design-system/components/modal.md +25 -4
  53. package/docs/design-system/components/native-select.md +18 -0
  54. package/docs/design-system/components/navigation-menu.md +15 -0
  55. package/docs/design-system/components/onboarding-step-list-item.md +16 -1
  56. package/docs/design-system/components/page-header.md +17 -1
  57. package/docs/design-system/components/pagination.md +31 -8
  58. package/docs/design-system/components/popover.md +19 -0
  59. package/docs/design-system/components/progress-slider.md +18 -0
  60. package/docs/design-system/components/progress.md +17 -0
  61. package/docs/design-system/components/radio-card.md +16 -0
  62. package/docs/design-system/components/radio-group.md +17 -0
  63. package/docs/design-system/components/resizable.md +15 -0
  64. package/docs/design-system/components/scroll-area.md +20 -1
  65. package/docs/design-system/components/segmented-control.md +71 -0
  66. package/docs/design-system/components/select.md +44 -7
  67. package/docs/design-system/components/sheet.md +17 -0
  68. package/docs/design-system/components/sidebar.md +17 -0
  69. package/docs/design-system/components/skeleton.md +18 -0
  70. package/docs/design-system/components/slideout.md +17 -0
  71. package/docs/design-system/components/slider.md +20 -0
  72. package/docs/design-system/components/social-button.md +21 -3
  73. package/docs/design-system/components/spinner.md +16 -0
  74. package/docs/design-system/components/steps.md +19 -0
  75. package/docs/design-system/components/table.md +36 -4
  76. package/docs/design-system/components/tabs.md +17 -0
  77. package/docs/design-system/components/tag.md +17 -0
  78. package/docs/design-system/components/textarea.md +16 -0
  79. package/docs/design-system/components/timeline.md +17 -0
  80. package/docs/design-system/components/toast.md +17 -0
  81. package/docs/design-system/components/toggle.md +17 -0
  82. package/docs/design-system/components/toolbar.md +21 -1
  83. package/docs/design-system/components/tooltip.md +18 -1
  84. package/docs/design-system/density-and-elevation.md +61 -0
  85. package/docs/design-system/direction-and-localization.md +23 -0
  86. package/docs/design-system/form-recipes.md +73 -0
  87. package/docs/design-system/gap-promotion-policy.md +21 -0
  88. package/docs/design-system/gap-promotion-report.md +100 -0
  89. package/docs/design-system/installation.md +68 -0
  90. package/docs/design-system/launch-comparison-shadcn.md +98 -0
  91. package/docs/design-system/registry-and-cli.md +30 -7
  92. package/docs/design-system/release-policy.md +30 -0
  93. package/docs/design-system/roadmap.md +14 -0
  94. package/docs/design-system/support-matrix.md +23 -0
  95. package/docs/design-system/tabs.md +1 -1
  96. package/docs/design-system/token-governance.md +23 -1
  97. package/package.json +30 -15
  98. package/registry/component-contract.json +40 -0
  99. package/registry/components/alert-dialog.tsx +2 -2
  100. package/registry/components/alert.tsx +101 -76
  101. package/registry/components/autocomplete.tsx +23 -9
  102. package/registry/components/avatar.tsx +14 -10
  103. package/registry/components/badge.tsx +18 -18
  104. package/registry/components/button-group.tsx +324 -5
  105. package/registry/components/button.tsx +38 -17
  106. package/registry/components/card.tsx +87 -62
  107. package/registry/components/carousel.tsx +67 -5
  108. package/registry/components/chart.tsx +36 -3
  109. package/registry/components/checkbox.tsx +3 -3
  110. package/registry/components/collapsible.tsx +1 -1
  111. package/registry/components/command.tsx +38 -4
  112. package/registry/components/context-menu.tsx +1 -1
  113. package/registry/components/date-picker.tsx +312 -135
  114. package/registry/components/expanded/ActivityFeed.tsx +9 -22
  115. package/registry/components/expanded/ActivityHeatmap.tsx +64 -0
  116. package/registry/components/expanded/Banner.tsx +3 -4
  117. package/registry/components/expanded/Breadcrumbs.tsx +8 -5
  118. package/registry/components/expanded/CatalogComponentsShowcase.tsx +16 -17
  119. package/registry/components/expanded/CatalogDivider.tsx +4 -3
  120. package/registry/components/expanded/EmptyState.tsx +1 -1
  121. package/registry/components/expanded/FileUpload.tsx +16 -7
  122. package/registry/components/expanded/OnboardingStepListItem.tsx +2 -6
  123. package/registry/components/expanded/PageHeader.tsx +47 -56
  124. package/registry/components/expanded/Slideout.tsx +29 -424
  125. package/registry/components/expanded/Steps.tsx +151 -13
  126. package/registry/components/expanded/Table.tsx +161 -82
  127. package/registry/components/expanded/Timeline.tsx +14 -27
  128. package/registry/components/expanded/activityFeed.css +9 -9
  129. package/registry/components/expanded/activityHeatmap.css +66 -0
  130. package/registry/components/expanded/banner.css +21 -11
  131. package/registry/components/expanded/breadcrumbs.css +2 -2
  132. package/registry/components/expanded/divider.css +1 -1
  133. package/registry/components/expanded/emptyState.css +1 -1
  134. package/registry/components/expanded/fileUpload.css +7 -7
  135. package/registry/components/expanded/onboardingStepListItem.css +2 -2
  136. package/registry/components/expanded/pageHeader.css +14 -11
  137. package/registry/components/expanded/slideout.css +10 -690
  138. package/registry/components/expanded/steps.css +78 -15
  139. package/registry/components/expanded/table.css +60 -69
  140. package/registry/components/expanded/timeline.css +19 -18
  141. package/registry/components/field.tsx +61 -8
  142. package/registry/components/input-content.ts +1 -0
  143. package/registry/components/input-otp.tsx +13 -3
  144. package/registry/components/input.tsx +68 -43
  145. package/registry/components/item.tsx +189 -0
  146. package/registry/components/kbd.tsx +111 -4
  147. package/registry/components/menu.tsx +87 -251
  148. package/registry/components/menubar.tsx +1 -1
  149. package/registry/components/modal.tsx +143 -103
  150. package/registry/components/native-select.tsx +2 -2
  151. package/registry/components/navigation-menu.tsx +1 -1
  152. package/registry/components/pagination.css +36 -0
  153. package/registry/components/pagination.tsx +88 -64
  154. package/registry/components/popover.tsx +162 -664
  155. package/registry/components/progress-slider.tsx +1 -1
  156. package/registry/components/radio-card.tsx +116 -87
  157. package/registry/components/resizable.tsx +36 -2
  158. package/registry/components/scroll-area.tsx +30 -6
  159. package/registry/components/segmented-control.tsx +87 -0
  160. package/registry/components/select-content.tsx +2 -2
  161. package/registry/components/select.tsx +86 -27
  162. package/registry/components/sheet.tsx +1 -1
  163. package/registry/components/sidebar.tsx +12 -6
  164. package/registry/components/skeleton.css +0 -3
  165. package/registry/components/social-button.tsx +59 -30
  166. package/registry/components/spinner.tsx +18 -55
  167. package/registry/components/table-elements.tsx +128 -0
  168. package/registry/components/tabs.css +1 -1
  169. package/registry/components/tabs.tsx +13 -14
  170. package/registry/components/tag.tsx +3 -3
  171. package/registry/components/textarea.tsx +3 -3
  172. package/registry/components/toast.tsx +16 -11
  173. package/registry/components/toggle.tsx +4 -4
  174. package/registry/components/toolbar.tsx +94 -22
  175. package/registry/components/tooltip.tsx +2 -2
  176. package/registry/examples/alert-demo.tsx +25 -5
  177. package/registry/examples/attribute-demo.tsx +1 -1
  178. package/registry/examples/autocomplete-demo.tsx +3 -3
  179. package/registry/examples/avatar-demo.tsx +14 -11
  180. package/registry/examples/badge-demo.tsx +1 -1
  181. package/registry/examples/button-demo.tsx +6 -6
  182. package/registry/examples/button-group-demo.tsx +23 -2
  183. package/registry/examples/card-demo.tsx +46 -8
  184. package/registry/examples/carousel-demo.tsx +20 -2
  185. package/registry/examples/chart-demo.tsx +1 -1
  186. package/registry/examples/checkbox-demo.tsx +5 -5
  187. package/registry/examples/collection-filter-bar-demo.tsx +135 -0
  188. package/registry/examples/command-demo.tsx +3 -3
  189. package/registry/examples/{expanded/command-bar-demo.tsx → command-palette-demo.tsx} +5 -15
  190. package/registry/examples/context-menu-demo.tsx +1 -1
  191. package/registry/examples/control-density-contract-demo.tsx +61 -0
  192. package/registry/examples/date-picker-demo.tsx +12 -12
  193. package/registry/examples/divider-demo.tsx +3 -3
  194. package/registry/examples/expanded/activity-heatmap-demo.tsx +29 -0
  195. package/registry/examples/expanded/banner-demo.tsx +1 -1
  196. package/registry/examples/expanded/breadcrumbs-demo.tsx +4 -4
  197. package/registry/examples/expanded/empty-state-demo.tsx +1 -1
  198. package/registry/examples/expanded/file-upload-demo.tsx +1 -1
  199. package/registry/examples/expanded/onboarding-step-demo.tsx +1 -1
  200. package/registry/examples/expanded/slideout-demo.tsx +2 -2
  201. package/registry/examples/expanded/steps-demo.tsx +1 -1
  202. package/registry/examples/expanded/tabs-demo.tsx +1 -1
  203. package/registry/examples/expanded/timeline-demo.tsx +1 -1
  204. package/registry/examples/hover-card-demo.tsx +2 -2
  205. package/registry/examples/input-demo.tsx +6 -6
  206. package/registry/examples/input-otp-demo.tsx +4 -4
  207. package/registry/examples/item-demo.tsx +46 -0
  208. package/registry/examples/kbd-demo.tsx +1 -1
  209. package/registry/examples/label-demo.tsx +1 -1
  210. package/registry/examples/menu-demo.tsx +1 -1
  211. package/registry/examples/modal-demo.tsx +67 -9
  212. package/registry/examples/navigation-menu-demo.tsx +1 -1
  213. package/registry/examples/pagination-demo.tsx +10 -7
  214. package/registry/examples/popover-demo.tsx +19 -19
  215. package/registry/examples/progress-demo.tsx +1 -1
  216. package/registry/examples/progress-slider-demo.tsx +1 -1
  217. package/registry/examples/radio-card-demo.tsx +4 -4
  218. package/registry/examples/radio-group-demo.tsx +2 -2
  219. package/registry/examples/resizable-demo.tsx +1 -1
  220. package/registry/examples/results-toolbar-demo.tsx +44 -0
  221. package/registry/examples/scroll-area-demo.tsx +3 -3
  222. package/registry/examples/segmented-control-demo.tsx +39 -0
  223. package/registry/examples/select-demo.tsx +1 -1
  224. package/registry/examples/sidebar-demo.tsx +5 -3
  225. package/registry/examples/slider-demo.tsx +3 -3
  226. package/registry/examples/social-button-demo.tsx +18 -8
  227. package/registry/examples/spinner-demo.tsx +13 -13
  228. package/registry/examples/tabs-demo.tsx +1 -1
  229. package/registry/examples/tag-demo.tsx +1 -1
  230. package/registry/examples/textarea-demo.tsx +4 -4
  231. package/registry/examples/toast-demo.tsx +1 -1
  232. package/registry/examples/toggle-demo.tsx +6 -6
  233. package/registry/examples/tooltip-demo.tsx +4 -4
  234. package/registry/guidance/USAGE.md +27 -0
  235. package/registry/hooks/use-direction.ts +193 -13
  236. package/registry/index.json +5668 -375
  237. package/registry/styles/globals.css +2404 -3999
  238. package/registry.json +156 -149
  239. package/schema/config.schema.json +11 -8
  240. package/schema/registry.schema.json +150 -45
  241. package/schema/tokens.schema.json +134 -34
  242. package/src/cli/command-line.js +194 -0
  243. package/src/cli/config-editors.js +9 -0
  244. package/src/cli/doctor.js +399 -0
  245. package/src/cli/file-transaction.js +295 -0
  246. package/src/cli/global-css.js +153 -0
  247. package/src/cli/index.js +567 -1613
  248. package/src/cli/install-plan.js +592 -0
  249. package/src/cli/install-receipt.js +171 -0
  250. package/src/cli/jsonc.js +203 -0
  251. package/src/cli/package-install-state.js +254 -0
  252. package/src/cli/package-manager.js +238 -0
  253. package/src/cli/package-plan.js +185 -0
  254. package/src/cli/package-version.js +97 -0
  255. package/src/cli/registry-query.js +207 -0
  256. package/src/cli/reporting.js +55 -0
  257. package/src/cli/schema-validation.js +19 -0
  258. package/src/cli/source-scanner.js +686 -0
  259. package/src/cli/vite-config.js +478 -0
  260. package/tokens/banhaten.tokens.json +4444 -331
  261. package/docs/design-system/components/command-bar.md +0 -57
  262. package/registry/components/expanded/BannerBoard.tsx +0 -225
  263. package/registry/components/expanded/CatalogTag.tsx +0 -85
  264. package/registry/components/expanded/CommandBar.tsx +0 -386
  265. package/registry/components/expanded/IconExplorer.tsx +0 -612
  266. package/registry/components/expanded/TimelineShowcase.tsx +0 -158
  267. package/registry/components/expanded/commandBar.css +0 -470
  268. package/registry/components/expanded/iconExplorer.css +0 -764
  269. package/registry/components/expanded/iconPacks.ts +0 -866
  270. package/registry/components/expanded/tag.css +0 -148
  271. package/registry/examples/expanded/icons-demo.tsx +0 -5
  272. package/tokens/Color mode.zip +0 -0
  273. package/tokens/Numbers.zip +0 -0
  274. package/tokens/Radius.zip +0 -0
  275. package/tokens/Theme.zip +0 -0
@@ -1,6 +1,6 @@
1
1
  # Social Button
2
2
 
3
- Social Button is the sign-in action primitive for supported identity providers. It includes Figma-matched platform styling, solid and outlined variants, icon-only mode, native focus-visible styling, and RTL labels.
3
+ Social Button is the sign-in action primitive for supported identity providers. It includes Figma-matched platform styling, solid and outlined variants, icon-only mode, native focus-visible styling, RTL layout, and explicit localized messages.
4
4
 
5
5
  ## API
6
6
 
@@ -15,6 +15,7 @@ Social Button is the sign-in action primitive for supported identity providers.
15
15
  | `variant` | `solid`, `outline` |
16
16
  | `size` | `default`, `icon` |
17
17
  | `label` | localized label override |
18
+ | `messages` | partial provider-label catalog selected by product locale |
18
19
 
19
20
  ## Token Contract
20
21
 
@@ -22,7 +23,7 @@ Social Button uses Banhaten control, typography, radius, focus, spacing, and sha
22
23
 
23
24
  ## RTL
24
25
 
25
- When direction is RTL, platform labels default to Arabic where provided. Icon and label spacing uses logical flex rhythm.
26
+ Icon and label spacing uses logical flex rhythm in RTL. Labels remain English unless `messages`, `label`, or text children select another language; `arabicSocialButtonMessages` is available for an explicit Arabic locale.
26
27
 
27
28
  ## Accessibility
28
29
 
@@ -43,5 +44,22 @@ Open the live component page or run `npx banhaten docs social-button` to inspect
43
44
  ## RTL Rules
44
45
 
45
46
  - `inheritsDirection`: true
46
- - `labels`: Defaults to the Arabic platform label when the document direction is RTL, and accepts an explicit label for nested RTL surfaces.
47
+ - `messages`: Direction controls layout only. Pass label, children, aria-label, or messages to localize provider names.
47
48
  - `spacing`: Uses logical label padding and flex gap so the icon/label order follows inherited direction.
49
+
50
+ <!-- registry-contract:start -->
51
+ ## Registry Contract
52
+
53
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
54
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
55
+
56
+ | Field | Values |
57
+ | --- | --- |
58
+ | `supportedExports` | `components/social-button.tsx: SocialButton, arabicSocialButtonMessages, socialButtonVariants, socialPlatformConfig` |
59
+ | `parts` | `SocialButton` |
60
+ | `registryDependencies` | None |
61
+ | `platforms` | `apple`, `facebook`, `google`, `linkedin`, `twitter`, `whatsapp` |
62
+ | `sizes` | `default`, `icon` |
63
+ | `tokens` | `--bh-bg-raised`, `--bh-bg-raised-hover`, `--bh-border-default`, `--bh-border-focus`, `--bh-border-width-default`, `--bh-content-default`, `--bh-icon-stroke-200`, `--bh-icon-stroke-225`, `--bh-opacity-50`, `--bh-social-apple-bg`, `--bh-social-apple-border`, `--bh-social-apple-fg`, `--bh-social-apple-hover`, `--bh-social-apple-icon`, `--bh-social-apple-icon-border`, `--bh-social-apple-outline-icon`, `--bh-social-apple-width`, `--bh-social-apple-width-rtl`, `--bh-social-button-bg`, `--bh-social-button-bg-hover`, `--bh-social-button-border`, `--bh-social-button-current-border`, `--bh-social-button-fg`, `--bh-social-button-focus-border`, `--bh-social-button-gap`, `--bh-social-button-height`, `--bh-social-button-icon`, `--bh-social-button-icon-size`, `--bh-social-button-label-padding-inline-end`, `--bh-social-button-padding-x`, `--bh-social-button-padding-y`, `--bh-social-button-radius`, `--bh-social-button-width`, `--bh-social-button-width-rtl`, `--bh-social-facebook-bg`, `--bh-social-facebook-fg`, `--bh-social-facebook-hover`, `--bh-social-facebook-icon`, `--bh-social-facebook-outline-icon`, `--bh-social-facebook-width`, `--bh-social-facebook-width-rtl`, `--bh-social-google-bg`, `--bh-social-google-border`, `--bh-social-google-fg`, `--bh-social-google-hover`, `--bh-social-google-width`, `--bh-social-google-width-rtl`, `--bh-social-linkedin-bg`, `--bh-social-linkedin-fg`, `--bh-social-linkedin-hover`, `--bh-social-linkedin-icon`, `--bh-social-linkedin-outline-icon`, `--bh-social-linkedin-width`, `--bh-social-linkedin-width-rtl`, `--bh-social-twitter-bg`, `--bh-social-twitter-border`, `--bh-social-twitter-fg`, `--bh-social-twitter-hover`, `--bh-social-twitter-icon`, `--bh-social-twitter-icon-border`, `--bh-social-twitter-outline-icon`, `--bh-social-twitter-width`, `--bh-social-twitter-width-rtl`, `--bh-social-whatsapp-bg`, `--bh-social-whatsapp-fg`, `--bh-social-whatsapp-hover`, `--bh-social-whatsapp-icon`, `--bh-social-whatsapp-outline-icon`, `--bh-social-whatsapp-width`, `--bh-social-whatsapp-width-rtl`, `--bh-text-button-font-size`, `--bh-text-button-font-weight`, `--bh-text-button-letter-spacing`, `--bh-text-button-line-height`, `--shadow-component-default`, `--shadow-social-button`, `--shadow-social-button-focus` |
64
+ | `variants` | `solid`, `outline` |
65
+ <!-- registry-contract:end -->
@@ -59,3 +59,19 @@ This component has no special RTL contract beyond inherited document direction a
59
59
  ## Accessibility
60
60
 
61
61
  Keep native semantics, accessible names, keyboard reachability, focus-visible treatment, and status/error announcements intact when composing this component.
62
+
63
+ <!-- registry-contract:start -->
64
+ ## Registry Contract
65
+
66
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
67
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
68
+
69
+ | Field | Values |
70
+ | --- | --- |
71
+ | `supportedExports` | `components/spinner.tsx: DynamicSpinner, Spinner` |
72
+ | `parts` | `Spinner`, `DynamicSpinner` |
73
+ | `registryDependencies` | None |
74
+ | `features` | `steady arc rotation`, `dynamic arc length`, `slower continuous rotation`, `text color inheritance`, `CSS variable sizing` |
75
+ | `modes` | `steady`, `dynamic` |
76
+ | `tokens` | `--bh-opacity-25`, `--bh-spinner-duration-dynamic`, `--bh-spinner-duration-steady`, `--bh-spinner-easing`, `--bh-spinner-size`, `--bh-spinner-stroke-width` |
77
+ <!-- registry-contract:end -->
@@ -61,3 +61,22 @@ This component has no special RTL contract beyond inherited document direction a
61
61
  ## Accessibility
62
62
 
63
63
  Keep native semantics, accessible names, keyboard reachability, focus-visible treatment, and status/error announcements intact when composing this component.
64
+
65
+ <!-- registry-contract:start -->
66
+ ## Registry Contract
67
+
68
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
69
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
70
+
71
+ | Field | Values |
72
+ | --- | --- |
73
+ | `supportedExports` | `components/expanded/Steps.tsx: HorizontalStepItem, ProgressSteps, Steps, VerticalStepItem` |
74
+ | `parts` | `HorizontalStepItem`, `ProgressSteps`, `Steps`, `VerticalStepItem` |
75
+ | `registryDependencies` | `button` |
76
+ | `modes` | `steps`, `progress-steps`, `horizontal-item`, `vertical-item` |
77
+ | `orientations` | `horizontal`, `vertical` |
78
+ | `states` | `complete`, `active`, `todo` |
79
+ | `tokens` | `--bh-bg-accent-purple-subtle`, `--bh-bg-inverse`, `--bh-border-accent-purple-strong`, `--bh-border-default`, `--bh-content-default`, `--bh-content-inverse`, `--bh-content-on-brand`, `--bh-content-subtle`, `--bh-control-default`, `--bh-font-family`, `--bh-font-weight-medium`, `--bh-font-weight-regular`, `--bh-font-weight-semibold`, `--bh-icon-stroke-300`, `--bh-interactive-brand-default`, `--bh-interactive-secondary-default`, `--bh-radius-full`, `--bh-radius-sm-4`, `--bh-space-3xl-16`, `--bh-space-5xl-24`, `--bh-space-9xl-64`, `--bh-space-md-8`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-space-xxxs-1`, `--bh-steps-horizontal-width`, `--bh-steps-indicator-panel-width`, `--bh-steps-vertical-width`, `--bh-text-base-letter-spacing`, `--bh-text-body-lg-medium-font-size`, `--bh-text-body-lg-medium-line-height`, `--bh-text-body-md-font-size`, `--bh-text-body-md-line-height`, `--bh-text-body-sm-regular-font-size`, `--bh-text-body-sm-regular-line-height`, `--bh-text-body-xs-regular-font-size` |
80
+ | `variants` | `icon`, `number` |
81
+ <!-- registry-contract:end -->
82
+ `ProgressSteps` covers compact bar progress and status-aware marker sequences used in setup and enrollment flows.
@@ -33,6 +33,19 @@ Figma references:
33
33
  filters={filters}
34
34
  pagination={{ pageSize: 10 }}
35
35
  />
36
+
37
+ <TableRoot aria-label="Compact audit data">
38
+ <TableHeader>
39
+ <TableRowElement>
40
+ <TableHead>Activity</TableHead>
41
+ </TableRowElement>
42
+ </TableHeader>
43
+ <TableBody>
44
+ <TableRowElement>
45
+ <TableCell>Member invited</TableCell>
46
+ </TableRowElement>
47
+ </TableBody>
48
+ </TableRoot>
36
49
  ```
37
50
 
38
51
  The table is composed from these parts:
@@ -43,6 +56,8 @@ The table is composed from these parts:
43
56
  - `TableCell`: the layout shell for any table item.
44
57
  - `TableItem`: the content variant rendered inside a cell.
45
58
  - `DataTable`: composed workflow shell for search, filters, actions, pagination, and table states.
59
+ - `DataTableSurface`: ARIA table surface for bespoke CSS-grid rows while keeping the table root owned by Banhaten.
60
+ - `TableRoot`, `TableHeader`, `TableBody`, `TableRowElement`, `TableHead`, and `TableCell`: owned semantic elements for product-specific read-only tables that do not fit the data-column API.
46
61
 
47
62
  Use semantic `<table>` markup when the table is mostly read-only data. Use an ARIA grid only when the product needs cell-level keyboard navigation. Interactive content inside cells, such as checkboxes, toggles, and actions, must remain real controls.
48
63
 
@@ -52,7 +67,7 @@ The Figma sample is `1024px` wide, but the implementation should be responsive.
52
67
 
53
68
  ```ts
54
69
  const exampleColumns = [
55
- { id: "select", width: 40, kind: "selection" },
70
+ { id: "select", width: 42, kind: "selection" },
56
71
  { id: "project", header: "Project Name", width: "fill", sortable: true },
57
72
  { id: "leader", header: "Project Leader", width: 203, sortable: true },
58
73
  { id: "status", header: "Status", width: 147, sortable: true },
@@ -72,7 +87,7 @@ RTL tables reverse the visual column order and align cell content to the end. Th
72
87
  | Body row | `sm` | `48px` | `44px` |
73
88
  | Body row | `lg` | `56px` | `56px` |
74
89
 
75
- Cell padding is `8px` on the inline axis. Inline content gap is `6px`; header label and sort icon gap is `4px`. The base checkbox and action columns use fixed dimensions so hover, selected, and icon states do not shift the table.
90
+ Cell padding is `12px` on the inline axis. The fixed `44px` action column keeps `8px` inline padding around its `28px` action button. Inline content gap is `6px`; header label and sort icon gap is `4px`. The base checkbox and action columns use fixed dimensions so hover, selected, and icon states do not shift the table.
76
91
 
77
92
  ## States
78
93
 
@@ -365,7 +380,7 @@ const filters = [
365
380
  - Progress bars are `8px` high and pill-shaped. In RTL, the filled segment grows from the right.
366
381
  - Badges are `24px` tall, pill-shaped, and use `11px / 14px` medium text.
367
382
  - Tags are `24px` tall with a 1px border and `13px / 20px` medium text.
368
- - Avatar-only and avatar-stack cells use 20px avatars in compact rows and 32px avatars where the `lg` item variant calls for it.
383
+ - Avatar-with-text cells use the shared 24px avatar in `sm` rows. Avatar-only and avatar-stack cells use 20px avatars. All three use 32px avatars in `lg` rows.
369
384
  - Action buttons are fixed `28px` in `sm` rows and `32px` in `lg` rows.
370
385
 
371
386
  ## Install
@@ -376,7 +391,7 @@ npx banhaten add table
376
391
 
377
392
  ## API
378
393
 
379
- Public exports: `Table`, `DataTable`.
394
+ Supported runtime exports: `DataTable`, `Table`, `DataTableSurface`, `TableBody`, `TableCell`, `TableHead`, `TableHeader`, `TableRoot`, `TableRowElement`.
380
395
 
381
396
  Use the live registry docs for the generated API table and source-backed examples.
382
397
 
@@ -395,3 +410,20 @@ Covered source files: `components/expanded/table.css`, `components/expanded/Tabl
395
410
  ## RTL Rules
396
411
 
397
412
  This component has no special RTL contract beyond inherited document direction and logical spacing.
413
+
414
+ <!-- registry-contract:start -->
415
+ ## Registry Contract
416
+
417
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
418
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
419
+
420
+ | Field | Values |
421
+ | --- | --- |
422
+ | `supportedExports` | `components/expanded/Table.tsx: DataTable, Table`, `components/table-elements.tsx: DataTableSurface, TableBody, TableCell, TableHead, TableHeader, TableRoot, TableRowElement` |
423
+ | `parts` | `Table`, `DataTable`, `DataTableSurface`, `TableRoot`, `TableHeader`, `TableBody`, `TableRowElement`, `TableHead`, `TableCell` |
424
+ | `registryDependencies` | `avatar`, `badge`, `button`, `checkbox`, `pagination`, `progress`, `spinner`, `tag`, `toggle`, `toolbar` |
425
+ | `modes` | `table`, `data-table` |
426
+ | `sizes` | `sm`, `lg` |
427
+ | `states` | `default`, `selected`, `disabled`, `loading`, `empty`, `error` |
428
+ | `tokens` | `--bh-avatar-fallback-font-size-md`, `--bh-avatar-fallback-font-size-xs`, `--bh-avatar-size-md`, `--bh-avatar-size-xs`, `--bh-bg-accent-amber-subtle`, `--bh-bg-accent-fuchsia-subtle`, `--bh-bg-accent-golden-default`, `--bh-bg-brand-default`, `--bh-bg-brand-soft`, `--bh-bg-danger-subtle`, `--bh-bg-default`, `--bh-bg-muted`, `--bh-bg-neutral-medium`, `--bh-bg-neutral-soft`, `--bh-bg-neutral-subtle`, `--bh-bg-raised`, `--bh-bg-success-default`, `--bh-bg-success-subtle`, `--bh-bg-warning-default`, `--bh-bg-warning-subtle`, `--bh-border-brand-strong`, `--bh-border-default`, `--bh-border-focus`, `--bh-border-subtle`, `--bh-content-accent-amber-strong`, `--bh-content-accent-fuchsia-strong`, `--bh-content-brand-default`, `--bh-content-danger-strong`, `--bh-content-default`, `--bh-content-muted`, `--bh-content-on-brand`, `--bh-content-subtle`, `--bh-content-success-default`, `--bh-content-warning-strong`, `--bh-control-default`, `--bh-duration-fast`, `--bh-easing-standard`, `--bh-focus-ring-width`, `--bh-font-family`, `--bh-font-weight-semibold`, `--bh-icon-stroke-190`, `--bh-icon-stroke-225`, `--bh-input-width`, `--bh-interactive-ghost-hover`, `--bh-opacity-0`, `--bh-opacity-100`, `--bh-opacity-muted`, `--bh-radius-full`, `--bh-radius-lg-8`, `--bh-radius-md-6`, `--bh-radius-sm-4`, `--bh-space-12xl-128`, `--bh-space-16xl-256`, `--bh-space-19xl-384`, `--bh-space-2xl-14`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-7xl-40`, `--bh-space-8xl-48`, `--bh-space-md-8`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--bh-space-xxxs-1`, `--bh-table-min-width`, `--bh-table-selection-column-min-width`, `--bh-text-base-letter-spacing`, `--bh-text-body-2xs-regular-font-size`, `--bh-text-body-2xs-regular-line-height`, `--bh-text-body-3xs-regular-font-size`, `--bh-text-body-3xs-regular-line-height`, `--bh-text-body-lg-semibold-font-size`, `--bh-text-body-lg-semibold-font-weight`, `--bh-text-body-lg-semibold-line-height`, `--bh-text-body-md-semibold-font-size`, `--bh-text-body-md-semibold-font-weight`, `--bh-text-body-md-semibold-line-height`, `--bh-text-body-sm-medium-font-weight`, `--bh-text-body-sm-regular-font-size`, `--bh-text-body-sm-regular-font-weight`, `--bh-text-body-sm-regular-line-height`, `--bh-text-body-xs-regular-font-size`, `--shadow-component-focus-ring` |
429
+ <!-- registry-contract:end -->
@@ -50,3 +50,20 @@ Open the live component page or run `npx banhaten docs tabs` to inspect source f
50
50
  - `keyboard`: Radix receives dir so arrow-key navigation follows the document direction.
51
51
  - `textDirection`: Trigger labels use dir="auto" by default for Arabic and English tab labels.
52
52
  - `spacing`: Uses inherited direction and logical inline spacing so underline, segmented, and rounded treatments mirror naturally.
53
+
54
+ <!-- registry-contract:start -->
55
+ ## Registry Contract
56
+
57
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
58
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
59
+
60
+ | Field | Values |
61
+ | --- | --- |
62
+ | `supportedExports` | `components/tabs.tsx: Tabs, TabsContent, TabsList, TabsRoot, TabsTrigger` |
63
+ | `parts` | `Tabs`, `TabsRoot`, `TabsList`, `TabsTrigger`, `TabsContent` |
64
+ | `registryDependencies` | None |
65
+ | `features` | `Radix keyboard behavior`, `controlled active index`, `controlled value`, `optional panels`, `full-width tabs` |
66
+ | `sizes` | `md`, `sm`, `xs` |
67
+ | `tokens` | `--bh-bg-default`, `--bh-bg-neutral-subtle`, `--bh-border-default`, `--bh-content-brand-default`, `--bh-content-default`, `--bh-content-subtle`, `--bh-font-family`, `--bh-font-weight-medium`, `--bh-opacity-60`, `--bh-radius-full`, `--bh-radius-lg-8`, `--bh-radius-md-6`, `--bh-space-3xl-16`, `--bh-space-6xl-32`, `--bh-space-7xl-40`, `--bh-space-8xl-48`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--bh-space-xxxs-1`, `--bh-text-body-md-regular-font-size`, `--bh-text-body-md-regular-font-weight`, `--bh-text-body-md-regular-letter-spacing`, `--bh-text-body-md-regular-line-height`, `--shadow-button-soft` |
68
+ | `variants` | `underline`, `segment`, `rounded` |
69
+ <!-- registry-contract:end -->
@@ -76,3 +76,20 @@ Open the live component page or run `npx banhaten docs tag` to inspect source fi
76
76
  ## Accessibility
77
77
 
78
78
  This component relies on `@radix-ui/react-slot` for its base accessibility behavior. Keep required labels, titles, descriptions, and focusable trigger/content relationships intact when composing it.
79
+
80
+ <!-- registry-contract:start -->
81
+ ## Registry Contract
82
+
83
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
84
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
85
+
86
+ | Field | Values |
87
+ | --- | --- |
88
+ | `supportedExports` | `components/tag.tsx: Tag, TagAvatar, TagCloseButton, TagDot, TagFlag, TagIcon, tagVariants` |
89
+ | `parts` | `Tag`, `TagDot`, `TagFlag`, `TagAvatar`, `TagIcon`, `TagCloseButton` |
90
+ | `registryDependencies` | None |
91
+ | `sizes` | `xs`, `md`, `lg` |
92
+ | `states` | `default`, `active`, `disabled` |
93
+ | `tokens` | `--bh-bg-accent-green-default`, `--bh-bg-always-dark`, `--bh-bg-always-white`, `--bh-bg-brand-subtle`, `--bh-bg-danger-default`, `--bh-bg-neutral-bold`, `--bh-bg-neutral-subtle`, `--bh-border-brand-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-focus`, `--bh-border-subtle`, `--bh-content-brand-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-on-neutral`, `--bh-control-default`, `--bh-control-md`, `--bh-icon-stroke-200`, `--bh-icon-stroke-225`, `--bh-interactive-ghost-hover`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-interactive-secondary-hover`, `--bh-opacity-30`, `--bh-radius-full`, `--bh-radius-xs-2`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-none`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-tag-active-border-width`, `--bh-tag-focus-ring-inset`, `--bh-tag-focus-ring-width`, `--bh-text-body-3xs-semibold-font-size`, `--bh-text-body-3xs-semibold-font-weight`, `--bh-text-body-3xs-semibold-line-height`, `--bh-text-body-md-medium-font-size`, `--bh-text-body-md-medium-font-weight`, `--bh-text-body-md-medium-letter-spacing`, `--bh-text-body-md-medium-line-height`, `--bh-text-body-sm-medium-font-size`, `--bh-text-body-sm-medium-font-weight`, `--bh-text-body-sm-medium-letter-spacing`, `--bh-text-body-sm-medium-line-height`, `--bh-text-body-xs-medium-font-size`, `--bh-text-body-xs-medium-font-weight`, `--bh-text-body-xs-medium-letter-spacing`, `--bh-text-body-xs-medium-line-height`, `--bh-z-raised`, `--shadow-button-focus` |
94
+ | `types` | `simple`, `dot`, `flag`, `avatar`, `icon` |
95
+ <!-- registry-contract:end -->
@@ -46,3 +46,19 @@ Open the live component page or run `npx banhaten docs textarea` to inspect sour
46
46
  - `inheritsDirection`: true
47
47
  - `textAlignment`: Uses text-start and dir="auto" so Arabic and English content align naturally.
48
48
  - `spacing`: Uses inherited direction and flex order so labels, helper icons, and tag chips mirror without physical left/right rules.
49
+
50
+ <!-- registry-contract:start -->
51
+ ## Registry Contract
52
+
53
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
54
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
55
+
56
+ | Field | Values |
57
+ | --- | --- |
58
+ | `supportedExports` | `components/textarea.tsx: Textarea` |
59
+ | `parts` | `Textarea` |
60
+ | `registryDependencies` | None |
61
+ | `modes` | `default`, `tags` |
62
+ | `states` | `placeholder`, `filled`, `disabled` |
63
+ | `tokens` | `--bh-bg-accent-blue-soft`, `--bh-border-danger-strong`, `--bh-border-default`, `--bh-border-disabled`, `--bh-border-focus`, `--bh-border-input`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-accent-blue-strong`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-subtle`, `--bh-control-md`, `--bh-font-weight-semibold`, `--bh-icon-stroke-225`, `--bh-icon-stroke-250`, `--bh-interactive-input-default`, `--bh-interactive-input-disabled`, `--bh-interactive-secondary-default`, `--bh-interactive-secondary-disabled`, `--bh-opacity-0`, `--bh-opacity-30`, `--bh-opacity-50`, `--bh-radius-full`, `--bh-space-xs-4`, `--bh-text-body-md-regular-font-size`, `--bh-text-body-md-regular-font-weight`, `--bh-text-body-md-regular-letter-spacing`, `--bh-text-body-md-regular-line-height`, `--bh-text-body-sm-medium-font-size`, `--bh-text-body-sm-medium-font-weight`, `--bh-text-body-sm-medium-letter-spacing`, `--bh-text-body-sm-medium-line-height`, `--bh-text-body-xs-medium-font-size`, `--bh-text-body-xs-medium-font-weight`, `--bh-text-body-xs-medium-letter-spacing`, `--bh-text-body-xs-medium-line-height`, `--bh-text-body-xs-regular-font-size`, `--bh-text-body-xs-regular-font-weight`, `--bh-text-body-xs-regular-letter-spacing`, `--bh-text-body-xs-regular-line-height`, `--bh-textarea-border`, `--bh-textarea-close-button-size`, `--bh-textarea-close-icon-size`, `--bh-textarea-focus-ring-inset`, `--bh-textarea-focus-ring-width`, `--bh-textarea-gap`, `--bh-textarea-helper-icon-size`, `--bh-textarea-icon-size`, `--bh-textarea-inline-gap`, `--bh-textarea-min-height`, `--bh-textarea-padding`, `--bh-textarea-radius`, `--bh-textarea-tag-avatar-font-size`, `--bh-textarea-tag-avatar-size`, `--bh-textarea-tag-height`, `--bh-textarea-width`, `--shadow-component-default`, `--shadow-textarea` |
64
+ <!-- registry-contract:end -->
@@ -79,3 +79,20 @@ This component has no special RTL contract beyond inherited document direction a
79
79
  ## Accessibility
80
80
 
81
81
  Keep native semantics, accessible names, keyboard reachability, focus-visible treatment, and status/error announcements intact when composing this component.
82
+
83
+ <!-- registry-contract:start -->
84
+ ## Registry Contract
85
+
86
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
87
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
88
+
89
+ | Field | Values |
90
+ | --- | --- |
91
+ | `supportedExports` | `components/expanded/Timeline.tsx: Timeline, TimelineItem` |
92
+ | `parts` | `Timeline`, `TimelineItem` |
93
+ | `registryDependencies` | None |
94
+ | `orientations` | `vertical`, `horizontal` |
95
+ | `states` | `finished`, `active`, `inactive` |
96
+ | `tokens` | `--bh-bg-brand-default`, `--bh-bg-default`, `--bh-bg-muted`, `--bh-border-brand-strong`, `--bh-border-default`, `--bh-border-subtle`, `--bh-content-default`, `--bh-content-on-brand`, `--bh-content-subtle`, `--bh-font-family`, `--bh-font-weight-regular`, `--bh-font-weight-semibold`, `--bh-icon-stroke-300`, `--bh-radius-full`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-9xl-64`, `--bh-space-lg-10`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--bh-space-xxxs-1`, `--bh-text-base-letter-spacing`, `--bh-text-body-2xs-regular-font-size`, `--bh-text-body-2xs-regular-line-height`, `--bh-text-body-md-font-size`, `--bh-text-body-md-line-height`, `--bh-text-body-sm-regular-font-size`, `--bh-text-body-sm-regular-line-height`, `--bh-timeline-grid-width`, `--bh-timeline-narrow-width`, `--bh-timeline-sidebar-width`, `--shadow-component-focus-ring` |
97
+ | `variants` | `default`, `icon` |
98
+ <!-- registry-contract:end -->
@@ -54,3 +54,20 @@ Open the live component page or run `npx banhaten docs toast` to inspect source
54
54
  - `inheritsDirection`: true
55
55
  - `placement`: side="end" resolves to top-right in LTR and top-left in RTL; side="start" resolves to the opposite edge.
56
56
  - `textDirection`: Toast content inherits the Toaster direction and uses tokenized typography classes.
57
+
58
+ <!-- registry-contract:start -->
59
+ ## Registry Contract
60
+
61
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
62
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
63
+
64
+ | Field | Values |
65
+ | --- | --- |
66
+ | `supportedExports` | `components/toast.tsx: Toaster, toast` |
67
+ | `parts` | `Toaster` |
68
+ | `registryDependencies` | None |
69
+ | `features` | `semantic shortcuts`, `action slot`, `close button`, `logical placement`, `toast promise support` |
70
+ | `intents` | `default`, `success`, `danger`, `warning`, `info` |
71
+ | `sides` | `start`, `end` |
72
+ | `tokens` | `--bh-bg-brand-subtle`, `--bh-bg-danger-subtle`, `--bh-bg-info-subtle`, `--bh-bg-neutral-soft`, `--bh-bg-raised`, `--bh-bg-success-subtle`, `--bh-bg-warning-subtle`, `--bh-border-danger-subtle`, `--bh-border-info-subtle`, `--bh-border-subtle`, `--bh-border-success-subtle`, `--bh-border-warning-subtle`, `--bh-content-brand-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-on-brand`, `--bh-content-subtle`, `--bh-content-success-default`, `--bh-content-warning-default`, `--bh-control-default`, `--bh-font-family`, `--bh-interactive-brand-default`, `--bh-radius-xl-10`, `--bh-space-lg-10`, `--bh-space-xs-4`, `--bh-text-body-sm-semibold-font-size`, `--bh-text-body-sm-semibold-font-weight`, `--bh-text-body-sm-semibold-letter-spacing`, `--bh-text-body-sm-semibold-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-toast-accent`, `--bh-toast-accent-bg`, `--shadow-component-default` |
73
+ <!-- registry-contract:end -->
@@ -77,3 +77,20 @@ Covered source files: `components/toggle.tsx`.
77
77
  ## Accessibility
78
78
 
79
79
  This component relies on `@radix-ui/react-switch` for its base accessibility behavior. Keep required labels, titles, descriptions, and focusable trigger/content relationships intact when composing it.
80
+
81
+ <!-- registry-contract:start -->
82
+ ## Registry Contract
83
+
84
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
85
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
86
+
87
+ | Field | Values |
88
+ | --- | --- |
89
+ | `supportedExports` | `components/toggle.tsx: Toggle, ToggleField, toggleFieldVariants, toggleVariants` |
90
+ | `parts` | `Toggle`, `ToggleField` |
91
+ | `registryDependencies` | None |
92
+ | `features` | `optional handle icons`, `leading label`, `trailing label`, `supporting text` |
93
+ | `sizes` | `sm`, `md` |
94
+ | `states` | `unchecked`, `checked`, `hover`, `focused`, `disabled` |
95
+ | `tokens` | `--bh-content-default`, `--bh-content-disabled`, `--bh-content-on-light`, `--bh-content-subtle`, `--bh-icon-stroke-250`, `--bh-interactive-switch-active`, `--bh-interactive-switch-active-disabled`, `--bh-interactive-switch-active-hover`, `--bh-interactive-switch-default`, `--bh-interactive-switch-disabled`, `--bh-interactive-switch-handle`, `--bh-interactive-switch-handle-disabled`, `--bh-interactive-switch-hover`, `--bh-menu-switch-handle-size`, `--bh-menu-switch-height`, `--bh-menu-switch-padding`, `--bh-menu-switch-width`, `--bh-radius-full`, `--bh-space-3xl-16`, `--bh-space-5xl-24`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-sm-6`, `--bh-space-xl-12`, `--bh-space-xxs-2`, `--bh-text-body-md-medium-font-weight`, `--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-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-toggle-handle-size`, `--bh-toggle-icon-size-md`, `--bh-toggle-icon-size-sm`, `--bh-toggle-offset`, `--shadow-md`, `--shadow-social-button-focus-ring` |
96
+ <!-- registry-contract:end -->
@@ -61,7 +61,7 @@ Set `dir="rtl"` on `Toolbar` or inherit it from the document. Sections, fields,
61
61
 
62
62
  ## API
63
63
 
64
- Public exports: `Toolbar`, `ToolbarSection`, `ToolbarSearch`, `ToolbarSelect`, `ToolbarButton`, `ToolbarIconButton`, `ToolbarFilterButton`, `ToolbarMoreButton`, `ToolbarBadge`, `ToolbarText`, `ToolbarSpacer`.
64
+ Supported runtime exports: `Toolbar`, `ToolbarBadge`, `ToolbarButton`, `ToolbarFilterButton`, `ToolbarIconButton`, `ToolbarMoreButton`, `ToolbarSearch`, `ToolbarSection`, `ToolbarSelect`, `ToolbarSpacer`, `ToolbarText`, `toolbarBadgeVariants`, `toolbarButtonVariants`, `toolbarSearchVariants`, `toolbarSectionVariants`, `toolbarSelectVariants`, `toolbarVariants`.
65
65
 
66
66
  | Contract | Values |
67
67
  | --- | --- |
@@ -83,3 +83,23 @@ Open the live component page or run `npx banhaten docs toolbar` to inspect sourc
83
83
  ## Accessibility
84
84
 
85
85
  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.
86
+
87
+ <!-- registry-contract:start -->
88
+ ## Registry Contract
89
+
90
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
91
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
92
+
93
+ | Field | Values |
94
+ | --- | --- |
95
+ | `supportedExports` | `components/toolbar.tsx: Toolbar, ToolbarBadge, ToolbarButton, ToolbarFilterButton, ToolbarIconButton, ToolbarMoreButton, ToolbarSearch, ToolbarSection, ToolbarSelect, ToolbarSpacer, ToolbarText, toolbarBadgeVariants, toolbarButtonVariants, toolbarSearchVariants, toolbarSectionVariants, toolbarSelectVariants, toolbarVariants` |
96
+ | `parts` | `Toolbar`, `ToolbarSection`, `ToolbarSearch`, `ToolbarSelect`, `ToolbarButton`, `ToolbarIconButton`, `ToolbarFilterButton`, `ToolbarMoreButton`, `ToolbarBadge`, `ToolbarText`, `ToolbarSpacer` |
97
+ | `registryDependencies` | `kbd` |
98
+ | `props.density` | `"compact" \| "default" \| "comfortable"; default "default"; Aligns Toolbar Search, Select, Text, and Button controls to the shared 32px, 36px, or 40px control contract.` |
99
+ | `props.shortcutKeys` | `readonly string[]; default null; Adds shared, platform-aware Kbd keycaps to ToolbarSearch without rebuilding a shortcut badge locally.` |
100
+ | `breakpoints` | `desktop`, `mobile` |
101
+ | `densities` | `compact`, `default`, `comfortable` |
102
+ | `layouts` | `inline`, `split`, `stack`, `wrap` |
103
+ | `styles` | `filter-fields`, `filter-actions`, `selection-actions`, `grouped-fields`, `field-grid`, `inline-search`, `filter-chips`, `saved-segment` |
104
+ | `tokens` | `--bh-bg-brand-subtle`, `--bh-bg-default-hover`, `--bh-bg-neutral-subtle`, `--bh-border-brand-strong`, `--bh-border-danger-strong`, `--bh-border-default`, `--bh-border-disabled`, `--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-md-height`, `--bh-button-md-padding-x`, `--bh-button-sm-height`, `--bh-button-sm-padding-x`, `--bh-button-sm-padding-y`, `--bh-button-xs-height`, `--bh-button-xs-padding-x`, `--bh-content-brand-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-on-brand`, `--bh-content-subtle`, `--bh-control-default`, `--bh-input-comfortable-height`, `--bh-input-comfortable-padding-x`, `--bh-input-content-gap`, `--bh-input-lg-height`, `--bh-input-lg-padding-x`, `--bh-input-md-height`, `--bh-input-md-padding-x`, `--bh-input-radius`, `--bh-input-width`, `--bh-interactive-brand-default`, `--bh-interactive-brand-disabled`, `--bh-interactive-brand-hover`, `--bh-interactive-brand-pressed`, `--bh-interactive-ghost-default`, `--bh-interactive-ghost-disabled`, `--bh-interactive-ghost-hover`, `--bh-interactive-ghost-pressed`, `--bh-interactive-input-default`, `--bh-interactive-input-disabled`, `--bh-interactive-outlined-default`, `--bh-interactive-outlined-disabled`, `--bh-interactive-outlined-hover`, `--bh-interactive-outlined-pressed`, `--bh-interactive-soft-default`, `--bh-interactive-soft-disabled`, `--bh-interactive-soft-hover`, `--bh-interactive-soft-pressed`, `--bh-radius-full`, `--bh-select-icon-size`, `--bh-select-icon-slot-size`, `--bh-select-trigger-padding-x`, `--bh-select-width`, `--bh-space-19xl-384`, `--bh-space-3xl-16`, `--bh-space-5xl-24`, `--bh-space-md-8`, `--bh-space-none`, `--bh-space-xl-12`, `--bh-space-xs-4`, `--bh-text-body-2xs-medium-font-size`, `--bh-text-body-2xs-medium-font-weight`, `--bh-text-body-2xs-medium-letter-spacing`, `--bh-text-body-2xs-medium-line-height`, `--bh-text-body-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-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-soft`, `--shadow-input`, `--shadow-input-focus-ring`, `--shadow-select-trigger` |
105
+ <!-- registry-contract:end -->
@@ -59,7 +59,7 @@ Tooltip content uses inherited direction and `dir="auto"` text. Top and bottom l
59
59
 
60
60
  ## API
61
61
 
62
- Public exports: `Tooltip`, `TooltipRoot`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider`, `TooltipPortal`, `TooltipShortcut`, `TooltipCloseButton`.
62
+ Supported runtime exports: `Tooltip`, `TooltipCloseButton`, `TooltipContent`, `TooltipPortal`, `TooltipProvider`, `TooltipRoot`, `TooltipShortcut`, `TooltipTrigger`, `tooltipContentVariants`.
63
63
 
64
64
  | Contract | Values |
65
65
  | --- | --- |
@@ -88,3 +88,20 @@ Covered source files: `components/tooltip.tsx`.
88
88
  ## Accessibility
89
89
 
90
90
  This component relies on `@radix-ui/react-tooltip` for its base accessibility behavior. Keep required labels, titles, descriptions, and focusable trigger/content relationships intact when composing it.
91
+
92
+ <!-- registry-contract:start -->
93
+ ## Registry Contract
94
+
95
+ This table is generated from `registry/index.json`; edit the component-owned source under `registry/catalog/components/`, not this table or the compiled index.
96
+ `supportedExports` is the exhaustive runtime import contract grouped by source module. `parts` is an ordered, non-exhaustive anatomy list.
97
+
98
+ | Field | Values |
99
+ | --- | --- |
100
+ | `supportedExports` | `components/tooltip.tsx: Tooltip, TooltipCloseButton, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipShortcut, TooltipTrigger, tooltipContentVariants` |
101
+ | `parts` | `Tooltip`, `TooltipRoot`, `TooltipTrigger`, `TooltipContent`, `TooltipProvider`, `TooltipPortal`, `TooltipShortcut`, `TooltipCloseButton` |
102
+ | `registryDependencies` | None |
103
+ | `pointerPositions` | `top-left`, `top-center`, `top-right`, `bottom-left`, `bottom-center`, `bottom-right`, `center-right`, `center-left`, `none` |
104
+ | `sizes` | `sm`, `lg` |
105
+ | `tokens` | `--bh-bg-always-dark`, `--bh-bg-neutral-soft`, `--bh-bg-neutral-subtle`, `--bh-bg-raised`, `--bh-border-inverse-subtle`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-default`, `--bh-content-on-color`, `--bh-content-subtle`, `--bh-font-family`, `--bh-icon-stroke-200`, `--bh-interactive-ghost-hover`, `--bh-radius-full`, `--bh-radius-sm-4`, `--bh-space-md-8`, `--bh-space-none`, `--bh-space-xs-4`, `--bh-space-xxxs-1`, `--bh-text-base-letter-spacing`, `--bh-text-body-2xs-medium-font-size`, `--bh-text-body-2xs-medium-font-weight`, `--bh-text-body-2xs-medium-letter-spacing`, `--bh-text-body-2xs-medium-line-height`, `--bh-text-body-2xs-regular-font-size`, `--bh-text-body-2xs-regular-font-weight`, `--bh-text-body-2xs-regular-letter-spacing`, `--bh-text-body-2xs-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-tooltip-bg`, `--bh-tooltip-border`, `--bh-tooltip-close-fg`, `--bh-tooltip-close-icon-size`, `--bh-tooltip-close-size`, `--bh-tooltip-fg`, `--bh-tooltip-lg-padding`, `--bh-tooltip-lg-radius`, `--bh-tooltip-lg-width`, `--bh-tooltip-max-width`, `--bh-tooltip-pointer-border-depth`, `--bh-tooltip-pointer-border-half-width`, `--bh-tooltip-pointer-border-offset`, `--bh-tooltip-pointer-depth`, `--bh-tooltip-pointer-half-width`, `--bh-tooltip-pointer-inline-offset`, `--bh-tooltip-pointer-offset`, `--bh-tooltip-pointer-width`, `--bh-tooltip-shadow`, `--bh-tooltip-shortcut-bg`, `--bh-tooltip-shortcut-border`, `--bh-tooltip-shortcut-height`, `--bh-tooltip-shortcut-min-width`, `--bh-tooltip-sm-padding-x`, `--bh-tooltip-sm-padding-y`, `--bh-tooltip-sm-radius`, `--bh-z-overlay`, `--bh-z-raised`, `--shadow-button-focus`, `--shadow-lg` |
106
+ | `variants` | `dark`, `default` |
107
+ <!-- registry-contract:end -->
@@ -0,0 +1,61 @@
1
+ # Density and Elevation
2
+
3
+ ## Density
4
+
5
+ Banhaten exposes one semantic density contract for controls that must align in a
6
+ product surface:
7
+
8
+ | Density | Height | Typical use |
9
+ | --- | ---: | --- |
10
+ | `compact` | 32px | Dense desktop tables and constrained toolbars |
11
+ | `default` | 36px | Standard forms, search, filters, and actions |
12
+ | `comfortable` | 40px | Prominent forms and less dense product areas |
13
+
14
+ Use `density` when Input, Select, Date Picker, Button, Button Group, Segmented
15
+ Control, or Toolbar controls sit in the same row. The semantic prop overrides
16
+ the component's legacy `size` prop. Existing `size` values remain supported for
17
+ compatibility and for component-specific variants outside the shared 32/36/40
18
+ control family.
19
+
20
+ ```tsx
21
+ <Input density="default" />
22
+ <Select density="default" />
23
+ <DatePicker density="default" />
24
+ <Button density="default">Apply</Button>
25
+ <ToggleGroup density="default" />
26
+ ```
27
+
28
+ Do not align controls by adding raw `h-*`, padding, radius, or font-size
29
+ utilities. Choose one semantic density at the containing form or toolbar and
30
+ pass it to every control. Compact controls are intended for pointer-led desktop
31
+ interfaces; products with touch requirements should prefer `comfortable` or
32
+ provide a larger interaction target around the control.
33
+
34
+ This is a component composition contract, not a global scale transform. It does
35
+ not silently resize navigation, cards, typography, or unrelated layout spacing.
36
+
37
+ ## Elevation
38
+
39
+ Elevation uses two layers:
40
+
41
+ - General steps: `--shadow-xs` through `--shadow-xl`.
42
+ - Semantic component aliases: `--shadow-component-*`, focus/danger rings, menus, controls, and component-specific aliases.
43
+
44
+ The five general steps mirror the Figma `Shadow/xs`, `Shadow/sm`, `Shadow/md`,
45
+ `Shadow/lg`, and `Shadow/xl` effect styles. They have no mode-specific bindings
46
+ in Figma, so the same recipes are used in light and dark modes.
47
+
48
+ | Step | Current component roles |
49
+ | --- | --- |
50
+ | `xs` | Compact raised details and file-upload error surfaces |
51
+ | `sm` | Quiet cards, panels, and staged content surfaces |
52
+ | `md` | Slider and toggle handles and floating banners |
53
+ | `lg` | Menus, select menus, popovers, tooltips, date surfaces, and dialogs |
54
+ | `xl` | Reserved for surfaces that need more separation than current dialogs |
55
+
56
+ Components consume the semantic alias that describes purpose rather than
57
+ selecting a visual step directly. Focus rings, inset borders, and the Figma
58
+ `Shadow/component/*` control effects remain separate from surface elevation.
59
+ The Shadows documentation groups aliases under their canonical effect and
60
+ distinguishes surface elevation, control strokes, focus rings, overlay
61
+ elevation, and intentional `none` values.
@@ -0,0 +1,23 @@
1
+ # Direction and Localization
2
+
3
+ Banhaten is Arabic and English-first, but text direction and language are separate contracts. Components resolve direction from an explicit `dir`, `DirectionProvider`, the nearest valid `[dir]` ancestor, or the document root—in that order. Direction changes layout, icon mirroring, and keyboard geometry; it never selects translated UI or accessibility copy.
4
+
5
+ Use a request-known direction provider for server rendering so the server markup, hydration snapshot, and first paint agree:
6
+
7
+ ```tsx
8
+ import { DirectionProvider } from "@/hooks/use-direction"
9
+ import {
10
+ arabicPaginationMessages,
11
+ Pagination,
12
+ } from "@/components/ui/pagination"
13
+
14
+ <DirectionProvider dir="rtl">
15
+ <Pagination messages={arabicPaginationMessages} />
16
+ </DirectionProvider>
17
+ ```
18
+
19
+ `DirectionProvider dir="rtl"` works equally well with English, Arabic, Hebrew, Persian, or Urdu. Choose a component's `messages` catalog from the product locale, or pass its direct label props. The exported Arabic catalogs are conveniences, not RTL defaults.
20
+
21
+ Without an explicit prop or provider, server output uses a stable LTR snapshot. After hydration, one shared subscription per document synchronizes consumers with the nearest nested boundary or document root. This avoids hydration mismatches and per-component document observers. For an RTL first paint, provide the request-known direction during SSR.
22
+
23
+ Use logical CSS properties (`start`, `end`, `margin-inline`, `padding-inline`) and `dir="auto"` for user-authored copy. Test mixed-language content, punctuation, numbers, icon mirroring, arrow-key behavior, focus order, portal content, and screen-reader names in every supported direction and locale combination.
@@ -0,0 +1,73 @@
1
+ # Form Recipes
2
+
3
+ ## Labeled field with validation
4
+
5
+ Compose `Field`, `FieldLabel`, `FieldControl`, `FieldDescription`, and `FieldError`. Associate the input with its label, keep help text stable, and announce errors only when validation has run.
6
+
7
+ ```tsx
8
+ <Field invalid={Boolean(error)}>
9
+ <FieldLabel htmlFor="email">Email</FieldLabel>
10
+ <FieldControl>
11
+ <Input id="email" state={error ? "error" : "default"} />
12
+ </FieldControl>
13
+ <FieldDescription>Use your work email.</FieldDescription>
14
+ {error ? <FieldError>{error}</FieldError> : null}
15
+ </Field>
16
+ ```
17
+
18
+ ## Selection and dates
19
+
20
+ Use `Select` for a bounded option set, `Autocomplete` for searchable options, and `DatePicker`/`DateRangePicker` for calendar input. Controlled values are preferred when validation, persistence, or URL state owns the result.
21
+
22
+ Do not emulate a date field with `Input`, a typed `@`, or a generic trailing icon. The Date Picker owns the calendar affordance, keyboard behavior, formatted value, and the same semantic density contract as the surrounding controls.
23
+
24
+ ## Golden recipe: collection filter bar
25
+
26
+ Use the complete [`CollectionFilterBarDemo`](../../registry/examples/collection-filter-bar-demo.tsx) recipe for collection and search screens. It establishes the approved composition:
27
+
28
+ - `ToolbarSearch` is full width and uses `shortcutKeys={["Mod", "F"]}` so Command and Control resolve by platform.
29
+ - `DatePicker` owns the From and To fields.
30
+ - `Select` owns Type and Order; `ToolbarSelect` is only a trigger-shaped primitive and is not a complete menu.
31
+ - Every control declares `density="default"`; responsive width classes do not replace component height, padding, radius, or typography.
32
+ - The Reset action uses the same density and resets all composed controls.
33
+
34
+ ```tsx
35
+ <form aria-label="Collection filters" data-recipe="collection-filter-bar">
36
+ <ToolbarSearch
37
+ aria-label="Search bookmarks"
38
+ density="default"
39
+ shortcutKeys={["Mod", "F"]}
40
+ width="full"
41
+ />
42
+ <div className="flex flex-wrap items-end gap-3">
43
+ <DatePicker density="default" triggerProps={{ "aria-label": "From" }} />
44
+ <DatePicker density="default" triggerProps={{ "aria-label": "To" }} />
45
+ <Select density="default" value="Everything">{/* items */}</Select>
46
+ <Select density="default" value="Recently bookmarked">{/* items */}</Select>
47
+ <ToolbarButton density="default" type="reset" variant="link">Reset</ToolbarButton>
48
+ </div>
49
+ </form>
50
+ ```
51
+
52
+ ## Golden recipe: results toolbar
53
+
54
+ Use the complete [`ResultsToolbarDemo`](../../registry/examples/results-toolbar-demo.tsx) recipe for result counts, layout selection, and batch actions. `SegmentedControl` is the approved content-width primitive for small mutually exclusive values such as cards per row.
55
+
56
+ ```tsx
57
+ <Toolbar aria-label="Bookmark results" layout="split" wrap>
58
+ <ToolbarText density="default"><strong>5,371</strong>&nbsp;bookmarks</ToolbarText>
59
+ <ToolbarSection align="end" wrap>
60
+ <SegmentedControl aria-label="Cards per row" defaultValue="4" density="default">
61
+ <SegmentedControlLabel>Cards / row</SegmentedControlLabel>
62
+ {[3, 4, 5, 6].map((count) => (
63
+ <SegmentedControlItem key={count} value={String(count)}>{count}</SegmentedControlItem>
64
+ ))}
65
+ </SegmentedControl>
66
+ <ToolbarButton density="default" variant="outline">Select</ToolbarButton>
67
+ </ToolbarSection>
68
+ </Toolbar>
69
+ ```
70
+
71
+ ## RTL forms
72
+
73
+ Set direction at the form or application boundary. Labels and helper text use logical alignment; OTP, calendar, pagination, and selection keyboard movement resolve the inherited direction. Localize labels, placeholders, validation messages, date formatting, and number formatting in the product layer.
@@ -0,0 +1,21 @@
1
+ # Gap promotion policy
2
+
3
+ Every visual-QA background records missing components, assets, composition patterns, and tokens as structured gap metadata. The promotion report groups recurring needs across backgrounds and flags any normalized need seen in three or more distinct scenarios.
4
+
5
+ Run:
6
+
7
+ ```sh
8
+ npm --prefix playground run report:gap-promotions
9
+ ```
10
+
11
+ The generated [Gap Promotion Report](./gap-promotion-report.md) is checked during background tests. Common needs are classified automatically; add `promotionKey` to a gap when two differently worded gaps represent the same reusable need or when a heuristic would group unrelated needs.
12
+
13
+ A candidate does not automatically become a component. Promotion requires:
14
+
15
+ 1. Evidence from at least three backgrounds.
16
+ 2. A smallest-stable API and explicit fit/avoid guidance.
17
+ 3. Semantic density, state, accessibility, and RTL contracts where applicable.
18
+ 4. Migration of at least one real background away from its local fallback.
19
+ 5. Behavior and visual tests before resolved gap metadata is removed.
20
+
21
+ The first application of this policy produced `SegmentedControl`, migrated the CRM Intelligence background to the shared primitive, and removed its former local segmented-control gap.