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,63 +1,72 @@
1
- # Menu
2
-
3
- Menu is a Radix DropdownMenu-backed action surface for contextual commands, navigation, progress rows, labels, captions, call-to-action rows, submenus, and rich item media.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <MenuRoot>
9
- <MenuTrigger>Open menu</MenuTrigger>
10
- <MenuContent width="menu">
11
- <MenuItem>Profile</MenuItem>
12
- <MenuSeparator />
13
- <MenuItem kind="button">Upgrade plan</MenuItem>
14
- </MenuContent>
15
- </MenuRoot>
16
- ```
17
-
18
- | Part | Purpose |
19
- | --- | --- |
20
- | `MenuRoot`, `MenuTrigger`, `MenuContent`, `MenuPortal` | Radix-backed menu shell |
21
- | `MenuItem`, `MenuItemContent`, media slots | interactive rows |
22
- | `MenuSub`, `MenuSubTrigger`, `MenuSubContent` | nested menus |
23
- | `MenuLabel`, `MenuCaption`, `MenuSeparator` | non-interactive structure |
24
-
25
- | Prop | Values |
26
- | --- | --- |
27
- | `width` | `menu`, `default`, `multiline`, `action`, `auto` |
28
- | `kind` | `default`, `multiline`, `action`, `progress`, `button` |
29
-
30
- ## Token Contract
31
-
32
- Menu uses Banhaten raised surface, menu shadow, item typography, border, radius, spacing, progress, badge, switch, and focus tokens.
33
-
34
- ## RTL
35
-
36
- Menu uses logical padding and flex direction so leading icons, trailing actions, badges, switches, meta text, and submenus mirror naturally. Directional icons should use `data-rtl-flip="true"`.
37
-
38
- ## Accessibility
39
-
40
- Radix provides menu roles, focus management, typeahead, keyboard navigation, Escape handling, and outside dismissal. Keep non-command copy in labels or captions, not disabled menu items.
41
-
42
- ## Install
43
-
44
- ```bash
45
- npx banhaten add menu
46
- ```
47
-
48
- ## Examples
49
-
50
- Primary registry example: `examples/menu-demo.tsx`.
51
-
52
- Open the live component page or run `npx banhaten docs menu` to inspect source files, install command, and examples.
53
-
54
- ## RTL Rules
55
-
56
- - `inheritsDirection`: true
57
- - `spacing`: Uses logical padding and flex direction so leading, trailing, badge, switch, right text, and action slots mirror naturally.
58
- - `directionalIconFlip`: Use data-rtl-flip="true" on chevrons and arrows that should mirror.
59
- - `textDirection`: Text slots use dir="auto" by default for Arabic and English labels.
60
-
1
+ # Menu
2
+
3
+ Menu is a Radix DropdownMenu-backed action surface for contextual commands, navigation, progress rows, labels, captions, call-to-action rows, submenus, and rich item media.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <MenuRoot>
9
+ <MenuTrigger>Open menu</MenuTrigger>
10
+ <MenuContent width="menu">
11
+ <MenuItem>Profile</MenuItem>
12
+ <MenuSeparator />
13
+ <MenuItem kind="button">Upgrade plan</MenuItem>
14
+ </MenuContent>
15
+ </MenuRoot>
16
+ ```
17
+
18
+ | Part | Purpose |
19
+ | --- | --- |
20
+ | `MenuRoot`, `MenuTrigger`, `MenuContent`, `MenuPortal` | Radix-backed menu shell |
21
+ | `MenuItem`, `MenuItemContent`, media slots | interactive rows |
22
+ | `MenuSub`, `MenuSubTrigger`, `MenuSubContent` | nested menus |
23
+ | `MenuLabel`, `MenuCaption`, `MenuSeparator` | non-interactive structure |
24
+
25
+ | Prop | Values |
26
+ | --- | --- |
27
+ | `width` | `menu`, `default`, `multiline`, `action`, `auto` |
28
+ | `kind` | `default`, `multiline`, `action`, `progress`, `button` |
29
+ | `MenuItem.onSelect` | `(event: Event) => void` |
30
+
31
+ `MenuItem.onSelect` uses Radix's native selection `Event`, not React's DOM text-selection event. Selection closes the menu by default; prevent it when a toggle or multi-select flow should remain open:
32
+
33
+ ```tsx
34
+ <MenuItem onSelect={(event: Event) => event.preventDefault()}>
35
+ Keep this menu open
36
+ </MenuItem>
37
+ ```
38
+
39
+ ## Token Contract
40
+
41
+ Menu uses Banhaten raised surface, menu shadow, item typography, border, radius, spacing, progress, badge, switch, and focus tokens. Leading glyphs are 18px inside 20px slots; trailing 16px affordances remain unchanged.
42
+
43
+ ## RTL
44
+
45
+ Menu uses logical padding and flex direction so leading icons, trailing actions, badges, switches, meta text, and submenus mirror naturally. Directional icons should use `data-rtl-flip="true"`.
46
+
47
+ ## Accessibility
48
+
49
+ Radix provides menu roles, focus management, typeahead, keyboard navigation, Escape handling, and outside dismissal. Keep non-command copy in labels or captions, not disabled menu items.
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ npx banhaten add menu
55
+ ```
56
+
57
+ ## Examples
58
+
59
+ Primary registry example: `examples/menu-demo.tsx`.
60
+
61
+ Open the live component page or run `npx banhaten docs menu` to inspect source files, install command, and examples.
62
+
63
+ ## RTL Rules
64
+
65
+ - `inheritsDirection`: true
66
+ - `spacing`: Uses logical padding and flex direction so leading, trailing, badge, switch, right text, and action slots mirror naturally.
67
+ - `directionalIconFlip`: Use data-rtl-flip="true" on chevrons and arrows that should mirror.
68
+ - `textDirection`: Text slots use dir="auto" by default for Arabic and English labels.
69
+
61
70
  <!-- registry-contract:start -->
62
71
  ## Registry Contract
63
72
 
@@ -69,8 +78,9 @@ This table is generated from `registry/index.json`; edit the component-owned sou
69
78
  | `supportedExports` | `components/menu.tsx: Menu, MenuCaption, MenuContent, MenuItem, MenuItemAction, MenuItemAvatar, MenuItemBadge, MenuItemContent, MenuItemDescription, MenuItemIcon, MenuItemMeta, MenuItemSwitch, MenuItemText, MenuItemTitle, MenuLabel, MenuPortal, MenuPreview, MenuProgress, MenuRoot, MenuSeparator, MenuSub, MenuSubContent, MenuSubTrigger, MenuSurface, MenuTrigger, menuItemContentVariants, menuItemIconVariants, menuItemVariants, menuVariants` |
70
79
  | `parts` | `Menu`, `MenuPreview`, `MenuSurface`, `MenuRoot`, `MenuTrigger`, `MenuContent`, `MenuPortal`, `MenuSub`, `MenuSubTrigger`, `MenuSubContent`, `MenuItem`, `MenuItemContent`, `MenuItemIcon`, `MenuItemAvatar`, `MenuItemText`, `MenuItemTitle`, `MenuItemDescription`, `MenuItemMeta`, `MenuItemBadge`, `MenuItemSwitch`, `MenuItemAction`, `MenuProgress`, `MenuSeparator`, `MenuLabel`, `MenuCaption` |
71
80
  | `registryDependencies` | None |
81
+ | `props.onSelect` | `(event: Event) => void; default null; MenuItem selection handler. Uses Radix's native selection Event, not React's DOM text-selection event; call event.preventDefault() to keep toggle or multi-select menus open.` |
72
82
  | `itemKinds` | `default`, `multiline`, `action`, `progress`, `button` |
73
83
  | `states` | `default`, `disabled` |
74
- | `tokens` | `--bh-bg-neutral-soft`, `--bh-bg-neutral-subtle`, `--bh-border-brand-strong`, `--bh-border-default`, `--bh-border-subtle`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-subtle`, `--bh-control-default`, `--bh-icon-stroke-300`, `--bh-interactive-indicator-default`, `--bh-interactive-outlined-default`, `--bh-interactive-outlined-hover`, `--bh-interactive-switch-active`, `--bh-interactive-switch-default`, `--bh-interactive-switch-disabled`, `--bh-interactive-switch-handle`, `--bh-interactive-switch-handle-disabled`, `--bh-menu-action-gap`, `--bh-menu-action-height`, `--bh-menu-action-padding-x`, `--bh-menu-badge-height`, `--bh-menu-badge-padding-x`, `--bh-menu-bg`, `--bh-menu-divider-padding-y`, `--bh-menu-gap`, `--bh-menu-icon-padding`, `--bh-menu-item-action-height`, `--bh-menu-item-action-width`, `--bh-menu-item-bg`, `--bh-menu-item-button-height`, `--bh-menu-item-caption-height`, `--bh-menu-item-content-compact-padding-y`, `--bh-menu-item-content-padding`, `--bh-menu-item-default-height`, `--bh-menu-item-default-width`, `--bh-menu-item-divider-height`, `--bh-menu-item-gap`, `--bh-menu-item-hover-bg`, `--bh-menu-item-label-height`, `--bh-menu-item-multiline-height`, `--bh-menu-item-multiline-width`, `--bh-menu-item-padding-x`, `--bh-menu-item-progress-height`, `--bh-menu-item-radius`, `--bh-menu-item-slot-gap`, `--bh-menu-label-padding-x`, `--bh-menu-leading-icon-size`, `--bh-menu-padding-y`, `--bh-menu-progress-gap`, `--bh-menu-progress-height`, `--bh-menu-radius`, `--bh-menu-switch-handle-size`, `--bh-menu-switch-height`, `--bh-menu-switch-padding`, `--bh-menu-switch-width`, `--bh-menu-trailing-icon-size`, `--bh-menu-width`, `--bh-opacity-60`, `--bh-radius-full`, `--bh-space-5xl-24`, `--bh-space-7xl-40`, `--bh-space-md-8`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--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-3xs-medium-font-size`, `--bh-text-body-3xs-medium-font-weight`, `--bh-text-body-3xs-medium-letter-spacing`, `--bh-text-body-3xs-medium-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-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-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`, `--shadow-menu` |
84
+ | `tokens` | `--bh-bg-neutral-soft`, `--bh-bg-neutral-subtle`, `--bh-border-brand-strong`, `--bh-border-default`, `--bh-border-subtle`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-content-subtle`, `--bh-control-default`, `--bh-icon-stroke-300`, `--bh-interactive-indicator-default`, `--bh-interactive-outlined-default`, `--bh-interactive-outlined-hover`, `--bh-interactive-switch-active`, `--bh-interactive-switch-default`, `--bh-interactive-switch-disabled`, `--bh-interactive-switch-handle`, `--bh-interactive-switch-handle-disabled`, `--bh-menu-action-gap`, `--bh-menu-action-height`, `--bh-menu-action-padding-x`, `--bh-menu-badge-height`, `--bh-menu-badge-padding-x`, `--bh-menu-bg`, `--bh-menu-divider-padding-y`, `--bh-menu-gap`, `--bh-menu-icon-padding`, `--bh-menu-item-action-height`, `--bh-menu-item-action-width`, `--bh-menu-item-bg`, `--bh-menu-item-button-height`, `--bh-menu-item-caption-height`, `--bh-menu-item-content-compact-padding-y`, `--bh-menu-item-content-padding`, `--bh-menu-item-default-height`, `--bh-menu-item-default-width`, `--bh-menu-item-divider-height`, `--bh-menu-item-gap`, `--bh-menu-item-hover-bg`, `--bh-menu-item-label-height`, `--bh-menu-item-multiline-height`, `--bh-menu-item-multiline-width`, `--bh-menu-item-padding-x`, `--bh-menu-item-progress-height`, `--bh-menu-item-radius`, `--bh-menu-item-slot-gap`, `--bh-menu-label-padding-x`, `--bh-menu-leading-icon-size`, `--bh-menu-leading-icon-slot-size`, `--bh-menu-padding-y`, `--bh-menu-progress-gap`, `--bh-menu-progress-height`, `--bh-menu-radius`, `--bh-menu-switch-handle-size`, `--bh-menu-switch-height`, `--bh-menu-switch-padding`, `--bh-menu-switch-width`, `--bh-menu-trailing-icon-size`, `--bh-menu-width`, `--bh-opacity-60`, `--bh-radius-full`, `--bh-space-5xl-24`, `--bh-space-7xl-40`, `--bh-space-md-8`, `--bh-space-xs-4`, `--bh-space-xxs-2`, `--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-3xs-medium-font-size`, `--bh-text-body-3xs-medium-font-weight`, `--bh-text-body-3xs-medium-letter-spacing`, `--bh-text-body-3xs-medium-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-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-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`, `--elevation-menu` |
75
85
  | `widths` | `menu`, `default`, `multiline`, `action`, `auto` |
76
86
  <!-- registry-contract:end -->
@@ -1,49 +1,49 @@
1
- # Menubar
2
-
3
- Menubar wraps Radix Menubar for application-style top menus.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <Menubar>
9
- <MenubarMenu>
10
- <MenubarTrigger>File</MenubarTrigger>
11
- <MenubarContent>
12
- <MenubarItem>New</MenubarItem>
13
- </MenubarContent>
14
- </MenubarMenu>
15
- </Menubar>
16
- ```
17
-
18
- ## Token Contract
19
-
20
- Menubar uses Banhaten menu, surface, border, shadow, hover, spacing, and body typography tokens.
21
-
22
- ## RTL
23
-
24
- Triggers, menu items, and shortcuts use logical spacing and inherited direction.
25
-
26
- ## Accessibility
27
-
28
- Radix provides menubar roles, keyboard navigation, open state, and submenu behavior.
29
-
30
- ## Install
31
-
32
- ```bash
33
- npx banhaten add menubar
34
- ```
35
-
36
- ## Examples
37
-
38
- Primary registry example: `examples/menubar-demo.tsx`.
39
-
40
- Open the live component page or run `npx banhaten docs menubar` to inspect source files, install command, and examples.
41
-
42
- ## RTL Rules
43
-
44
- - `inheritsDirection`: true
45
- - `spacing`: Triggers, items, and shortcuts use logical spacing.
46
-
1
+ # Menubar
2
+
3
+ Menubar wraps Radix Menubar for application-style top menus.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <Menubar>
9
+ <MenubarMenu>
10
+ <MenubarTrigger>File</MenubarTrigger>
11
+ <MenubarContent>
12
+ <MenubarItem>New</MenubarItem>
13
+ </MenubarContent>
14
+ </MenubarMenu>
15
+ </Menubar>
16
+ ```
17
+
18
+ ## Token Contract
19
+
20
+ Menubar uses Banhaten menu, surface, border, shadow, hover, spacing, and body typography tokens.
21
+
22
+ ## RTL
23
+
24
+ Triggers, menu items, and shortcuts use logical spacing and inherited direction.
25
+
26
+ ## Accessibility
27
+
28
+ Radix provides menubar roles, keyboard navigation, open state, and submenu behavior.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ npx banhaten add menubar
34
+ ```
35
+
36
+ ## Examples
37
+
38
+ Primary registry example: `examples/menubar-demo.tsx`.
39
+
40
+ Open the live component page or run `npx banhaten docs menubar` to inspect source files, install command, and examples.
41
+
42
+ ## RTL Rules
43
+
44
+ - `inheritsDirection`: true
45
+ - `spacing`: Triggers, items, and shortcuts use logical spacing.
46
+
47
47
  <!-- registry-contract:start -->
48
48
  ## Registry Contract
49
49
 
@@ -56,5 +56,5 @@ This table is generated from `registry/index.json`; edit the component-owned sou
56
56
  | `parts` | `Menubar`, `MenubarMenu`, `MenubarTrigger`, `MenubarContent`, `MenubarItem`, `MenubarCheckboxItem`, `MenubarRadioItem`, `MenubarLabel`, `MenubarSeparator`, `MenubarShortcut` |
57
57
  | `registryDependencies` | None |
58
58
  | `features` | `top menu`, `keyboard navigation`, `checkbox items`, `radio items`, `shortcuts` |
59
- | `tokens` | `--bh-bg-raised`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-interactive-ghost-hover`, `--bh-interactive-soft-default`, `--bh-menu-item-default-height`, `--bh-menu-item-hover-bg`, `--bh-menu-width`, `--bh-radius-lg-8`, `--bh-radius-md-6`, `--bh-radius-xl-10`, `--bh-space-3xl-16`, `--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-xs-4`, `--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-sm-regular-font-size`, `--bh-text-body-sm-regular-font-weight`, `--bh-text-body-sm-regular-letter-spacing`, `--bh-text-body-sm-regular-line-height`, `--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-popover`, `--shadow-component-default`, `--shadow-menu` |
59
+ | `tokens` | `--bh-bg-raised`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-muted`, `--bh-interactive-ghost-hover`, `--bh-interactive-soft-default`, `--bh-menu-item-default-height`, `--bh-menu-item-hover-bg`, `--bh-menu-width`, `--bh-radius-lg-8`, `--bh-radius-md-6`, `--bh-radius-xl-10`, `--bh-space-3xl-16`, `--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-xs-4`, `--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-sm-regular-font-size`, `--bh-text-body-sm-regular-font-weight`, `--bh-text-body-sm-regular-letter-spacing`, `--bh-text-body-sm-regular-line-height`, `--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-popover`, `--elevation-component-default`, `--elevation-menu` |
60
60
  <!-- registry-contract:end -->
@@ -1,107 +1,107 @@
1
- # Modal
2
-
3
- `Modal` presents a focused dialog surface for decisions and blocking workflows. `ConfirmModal` adds the constrained alert-dialog/confirm pattern for consequential actions.
4
-
5
- Figma reference: `Design system 3.0 Copy / Modal`, node `227:5480`.
6
-
7
- ## Variants
8
-
9
- The implementation covers the six-node Modal matrix from Figma:
10
-
11
- | Prop | Values |
12
- | --- | --- |
13
- | `size` | `sm`, `default`, `lg` |
14
- | `dir` | `ltr`, `rtl` |
15
-
16
- ## API
17
-
18
- ```tsx
19
- <Modal size="default" />
20
- <Modal dir="rtl" messages={arabicModalMessages} size="lg" />
21
- <ConfirmModal intent="danger" confirmLabel="Delete project" />
22
- ```
23
-
24
- | Prop | Default |
25
- | --- | --- |
26
- | `size` | `sm` |
27
- | `dir` | inherited |
28
- | `title` | English default; overrides `messages.title` |
29
- | `description` | English default; overrides `messages.description` |
30
- | `messages` | partial localized Modal message catalog |
31
- | `closeLabel` | overrides `messages.closeLabel` |
32
- | `showIcon` | `true` |
33
- | `showCloseButton` | `true` |
34
- | `showDivider` | `true` |
35
- | `showFooter` | `true` |
36
- | `showCheckbox` | `true` |
37
- | `footer` | none |
38
-
39
- `ConfirmModal` also accepts:
40
-
41
- | Prop | Default |
42
- | --- | --- |
43
- | `intent` | `danger` |
44
- | `messages` | partial localized ConfirmModal message catalog |
45
- | `confirmLabel` / `cancelLabel` | English; direct props override `messages` |
46
- | `confirmLoading` | `false` |
47
- | `confirmDisabled` | `false` |
48
- | `preventOutsideDismiss` | `true` |
49
- | `closeOnConfirm` / `closeOnCancel` | `true` |
50
- | `onConfirm` / `onCancel` | none |
51
-
52
- ## Pixel Rules
53
-
54
- - Small, Default, and Large modal widths are `440px`, `560px`, and `700px`.
55
- - The shell uses `--bh-radius-2xl-12`.
56
- - Header padding is `20px 20px 8px`, with logical end padding reserved for the close button.
57
- - Body padding is `10px 20px 20px`.
58
- - Footer padding is `16px 20px`, with a `10px` gap.
59
- - Actions reuse `Button` with `size="sm"`, `variant="soft"` for the secondary action, and the default variant for the primary action.
60
- - Confirm actions reuse `Button` with `variant="danger"`, `variant="warning"`, or `variant="default"` from the selected intent.
61
- - The opt-out control reuses `Checkbox`.
62
- - Loading confirm actions reuse the Banhaten `Spinner` component.
63
-
64
- ## Token Contract
65
-
66
- The component consumes existing Banhaten variables:
67
-
68
- - Surface: `--bh-bg-raised`, `--bh-bg-backdrop`, `--bh-bg-danger-subtle`, `--bh-bg-warning-subtle`
69
- - Border: `--bh-border-subtle`
70
- - Content: `--bh-content-default`, `--bh-content-subtle`, `--bh-content-danger-default`, `--bh-content-warning-default`
71
- - Shape: `--bh-radius-2xl-12`, `--bh-radius-full`
72
- - Space: `--bh-space-xs-4`, `--bh-space-sm-6`, `--bh-space-md-8`, `--bh-space-lg-10`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-8xl-48`, `--bh-space-9xl-64`
73
- - Type: `--bh-text-heading-sm-semibold-*`, `--bh-text-body-md-regular-*`
74
- - Elevation: `--shadow-component-default`, `--shadow-button-focus`, `--shadow-button-danger-focus`
75
-
76
- ## Accessibility
77
-
78
- - `ModalContent` is backed by Radix Dialog for focus trap, Escape, outside-click dismissal, and ARIA dialog semantics.
79
- - `ModalTitle` and `ModalDescription` map to Radix dialog title and description primitives.
80
- - The close affordance is a real button through `ModalCloseButton`.
81
- - `ConfirmModal` sets `role="alertdialog"`, focuses the cancel action first when present, disables outside-pointer dismissal by default, and can optionally prevent Escape dismissal.
82
- - `ModalSurface` is presentational and intended for static documentation or visual comparison, not live modal behavior.
83
- - Direction never selects modal copy. Choose `messages` from the product locale; direct title, description, action, and close-label props have highest precedence.
84
-
85
- ## Install
86
-
87
- ```bash
88
- npx banhaten add modal
89
- ```
90
-
91
- ## Examples
92
-
93
- Primary registry example: `examples/modal-demo.tsx`.
94
-
95
- Open the live component page or run `npx banhaten docs modal` to inspect source files, install command, and examples.
96
-
97
- ## RTL Rules
98
-
99
- - `inheritsDirection`: true
100
- - `closePlacement`: Close uses logical inline-end placement so it moves to the left side in RTL.
101
- - `footerOrder`: The checkbox and action cluster use inherited direction and logical gaps so their order mirrors naturally.
102
- - `messages`: Direction does not select language. Modal and ConfirmModal accept explicit message catalogs plus direct label overrides.
103
- - `textDirection`: Title, description, checkbox label, confirm labels, and actions use dir="auto" for Arabic and English copy.
104
-
1
+ # Modal
2
+
3
+ `Modal` presents a focused dialog surface for decisions and blocking workflows. `ConfirmModal` adds the constrained alert-dialog/confirm pattern for consequential actions.
4
+
5
+ Figma reference: `Design system 3.0 Copy / Modal`, node `227:5480`.
6
+
7
+ ## Variants
8
+
9
+ The implementation covers the six-node Modal matrix from Figma:
10
+
11
+ | Prop | Values |
12
+ | --- | --- |
13
+ | `size` | `sm`, `default`, `lg` |
14
+ | `dir` | `ltr`, `rtl` |
15
+
16
+ ## API
17
+
18
+ ```tsx
19
+ <Modal size="default" />
20
+ <Modal dir="rtl" messages={arabicModalMessages} size="lg" />
21
+ <ConfirmModal intent="danger" confirmLabel="Delete project" />
22
+ ```
23
+
24
+ | Prop | Default |
25
+ | --- | --- |
26
+ | `size` | `sm` |
27
+ | `dir` | inherited |
28
+ | `title` | English default; overrides `messages.title` |
29
+ | `description` | English default; overrides `messages.description` |
30
+ | `messages` | partial localized Modal message catalog |
31
+ | `closeLabel` | overrides `messages.closeLabel` |
32
+ | `showIcon` | `true` |
33
+ | `showCloseButton` | `true` |
34
+ | `showDivider` | `true` |
35
+ | `showFooter` | `true` |
36
+ | `showCheckbox` | `true` |
37
+ | `footer` | none |
38
+
39
+ `ConfirmModal` also accepts:
40
+
41
+ | Prop | Default |
42
+ | --- | --- |
43
+ | `intent` | `danger` |
44
+ | `messages` | partial localized ConfirmModal message catalog |
45
+ | `confirmLabel` / `cancelLabel` | English; direct props override `messages` |
46
+ | `confirmLoading` | `false` |
47
+ | `confirmDisabled` | `false` |
48
+ | `preventOutsideDismiss` | `true` |
49
+ | `closeOnConfirm` / `closeOnCancel` | `true` |
50
+ | `onConfirm` / `onCancel` | none |
51
+
52
+ ## Pixel Rules
53
+
54
+ - Small, Default, and Large modal widths are `440px`, `560px`, and `700px`.
55
+ - The shell uses `--bh-radius-2xl-12`.
56
+ - Header padding is `20px 20px 8px`, with logical end padding reserved for the close button.
57
+ - Body padding is `10px 20px 20px`.
58
+ - Footer padding is `16px 20px`, with a `10px` gap.
59
+ - Actions reuse `Button` with `size="sm"`, `variant="soft"` for the secondary action, and the default variant for the primary action.
60
+ - Confirm actions reuse `Button` with `variant="danger"`, `variant="warning"`, or `variant="default"` from the selected intent.
61
+ - The opt-out control reuses `Checkbox`.
62
+ - Loading confirm actions reuse the Banhaten `Spinner` component.
63
+
64
+ ## Token Contract
65
+
66
+ The component consumes existing Banhaten variables:
67
+
68
+ - Surface: `--bh-bg-raised`, `--bh-bg-backdrop`, `--bh-bg-danger-subtle`, `--bh-bg-warning-subtle`
69
+ - Border: `--bh-border-subtle`
70
+ - Content: `--bh-content-default`, `--bh-content-subtle`, `--bh-content-danger-default`, `--bh-content-warning-default`
71
+ - Shape: `--bh-radius-2xl-12`, `--bh-radius-full`
72
+ - Space: `--bh-space-xs-4`, `--bh-space-sm-6`, `--bh-space-md-8`, `--bh-space-lg-10`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-8xl-48`, `--bh-space-9xl-64`
73
+ - Type: `--bh-text-heading-sm-semibold-*`, `--bh-text-body-md-regular-*`
74
+ - Elevation: `--elevation-component-default`, `--elevation-button-focus`, `--elevation-button-danger-focus`
75
+
76
+ ## Accessibility
77
+
78
+ - `ModalContent` is backed by Radix Dialog for focus trap, Escape, outside-click dismissal, and ARIA dialog semantics.
79
+ - `ModalTitle` and `ModalDescription` map to Radix dialog title and description primitives.
80
+ - The close affordance is a real button through `ModalCloseButton`.
81
+ - `ConfirmModal` sets `role="alertdialog"`, focuses the cancel action first when present, disables outside-pointer dismissal by default, and can optionally prevent Escape dismissal.
82
+ - `ModalSurface` is presentational and intended for static documentation or visual comparison, not live modal behavior.
83
+ - Direction never selects modal copy. Choose `messages` from the product locale; direct title, description, action, and close-label props have highest precedence.
84
+
85
+ ## Install
86
+
87
+ ```bash
88
+ npx banhaten add modal
89
+ ```
90
+
91
+ ## Examples
92
+
93
+ Primary registry example: `examples/modal-demo.tsx`.
94
+
95
+ Open the live component page or run `npx banhaten docs modal` to inspect source files, install command, and examples.
96
+
97
+ ## RTL Rules
98
+
99
+ - `inheritsDirection`: true
100
+ - `closePlacement`: Close uses logical inline-end placement so it moves to the left side in RTL.
101
+ - `footerOrder`: The checkbox and action cluster use inherited direction and logical gaps so their order mirrors naturally.
102
+ - `messages`: Direction does not select language. Modal and ConfirmModal accept explicit message catalogs plus direct label overrides.
103
+ - `textDirection`: Title, description, checkbox label, confirm labels, and actions use dir="auto" for Arabic and English copy.
104
+
105
105
  <!-- registry-contract:start -->
106
106
  ## Registry Contract
107
107
 
@@ -115,5 +115,5 @@ This table is generated from `registry/index.json`; edit the component-owned sou
115
115
  | `registryDependencies` | `alert-dialog`, `button`, `checkbox`, `spinner` |
116
116
  | `intents` | `default`, `warning`, `danger` |
117
117
  | `sizes` | `sm`, `default`, `lg` |
118
- | `tokens` | `--bh-bg-backdrop`, `--bh-bg-danger-subtle`, `--bh-bg-raised`, `--bh-bg-warning-subtle`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-subtle`, `--bh-content-warning-default`, `--bh-icon-stroke-200`, `--bh-interactive-ghost-hover`, `--bh-modal-action-label-padding-x`, `--bh-modal-border`, `--bh-modal-width`, `--bh-radius-2xl-12`, `--bh-radius-full`, `--bh-space-12xl-128`, `--bh-space-16xl-256`, `--bh-space-19xl-384`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-8xl-48`, `--bh-space-9xl-64`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-sm-6`, `--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-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`, `--bh-z-overlay`, `--shadow-button-focus`, `--shadow-lg`, `--shadow-modal` |
118
+ | `tokens` | `--bh-bg-backdrop`, `--bh-bg-danger-subtle`, `--bh-bg-raised`, `--bh-bg-warning-subtle`, `--bh-border-subtle`, `--bh-border-width-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-subtle`, `--bh-content-warning-default`, `--bh-icon-stroke-200`, `--bh-interactive-ghost-hover`, `--bh-modal-action-label-padding-x`, `--bh-modal-border`, `--bh-modal-width`, `--bh-radius-2xl-12`, `--bh-radius-full`, `--bh-space-12xl-128`, `--bh-space-16xl-256`, `--bh-space-19xl-384`, `--bh-space-3xl-16`, `--bh-space-4xl-20`, `--bh-space-5xl-24`, `--bh-space-6xl-32`, `--bh-space-8xl-48`, `--bh-space-9xl-64`, `--bh-space-lg-10`, `--bh-space-md-8`, `--bh-space-sm-6`, `--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-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`, `--bh-z-overlay`, `--elevation-06`, `--elevation-button-focus`, `--elevation-modal` |
119
119
  <!-- registry-contract:end -->
@@ -1,56 +1,56 @@
1
- # Native Select
2
-
3
- Native Select is a tokenized native `<select>` field for platform forms, mobile fallback, and lightweight option sets.
4
-
5
- ## API
6
-
7
- ```tsx
8
- <NativeSelect
9
- label="Workspace"
10
- options={[
11
- { label: "Design", value: "design" },
12
- { label: "Engineering", value: "engineering" },
13
- ]}
14
- />
15
- ```
16
-
17
- | Prop | Values |
18
- | --- | --- |
19
- | `size` | `md`, `lg` |
20
- | `variant` | `default`, `soft` |
21
- | `state` | `default`, `filled`, `error`, `disabled` |
22
- | `options` | array of `{ label, value, disabled }` |
23
-
24
- ## Token Contract
25
-
26
- Native Select reuses Banhaten select width, label, helper, trigger, border, focus, icon, and validation tokens.
27
-
28
- ## RTL
29
-
30
- Native Select accepts `dir` and uses logical padding plus an inline-end chevron.
31
-
32
- ## Accessibility
33
-
34
- Prefer `label` or an external `<Label htmlFor>` and use helper or error copy for validation context.
35
-
36
- ## Install
37
-
38
- ```bash
39
- npx banhaten add native-select
40
- ```
41
-
42
- ## Examples
43
-
44
- Primary registry example: `examples/native-select-demo.tsx`.
45
-
46
- Open the live component page or run `npx banhaten docs native-select` to inspect source files, install command, and examples.
47
-
48
- ## RTL Rules
49
-
50
- - `inheritsDirection`: true
51
- - `spacing`: Uses logical padding and inline-end chevron placement.
52
- - `textDirection`: Label and helper copy use dir="auto" through Label and helper text.
53
-
1
+ # Native Select
2
+
3
+ Native Select is a tokenized native `<select>` field for platform forms, mobile fallback, and lightweight option sets.
4
+
5
+ ## API
6
+
7
+ ```tsx
8
+ <NativeSelect
9
+ label="Workspace"
10
+ options={[
11
+ { label: "Design", value: "design" },
12
+ { label: "Engineering", value: "engineering" },
13
+ ]}
14
+ />
15
+ ```
16
+
17
+ | Prop | Values |
18
+ | --- | --- |
19
+ | `size` | `md`, `lg` |
20
+ | `variant` | `default`, `soft` |
21
+ | `state` | `default`, `filled`, `error`, `disabled` |
22
+ | `options` | array of `{ label, value, disabled }` |
23
+
24
+ ## Token Contract
25
+
26
+ Native Select reuses Banhaten select width, label, helper, trigger, border, focus, icon, and validation tokens.
27
+
28
+ ## RTL
29
+
30
+ Native Select accepts `dir` and uses logical padding plus an inline-end chevron.
31
+
32
+ ## Accessibility
33
+
34
+ Prefer `label` or an external `<Label htmlFor>` and use helper or error copy for validation context.
35
+
36
+ ## Install
37
+
38
+ ```bash
39
+ npx banhaten add native-select
40
+ ```
41
+
42
+ ## Examples
43
+
44
+ Primary registry example: `examples/native-select-demo.tsx`.
45
+
46
+ Open the live component page or run `npx banhaten docs native-select` to inspect source files, install command, and examples.
47
+
48
+ ## RTL Rules
49
+
50
+ - `inheritsDirection`: true
51
+ - `spacing`: Uses logical padding and inline-end chevron placement.
52
+ - `textDirection`: Label and helper copy use dir="auto" through Label and helper text.
53
+
54
54
  <!-- registry-contract:start -->
55
55
  ## Registry Contract
56
56
 
@@ -65,6 +65,6 @@ This table is generated from `registry/index.json`; edit the component-owned sou
65
65
  | `features` | `options array`, `native children`, `label`, `helper text`, `error text` |
66
66
  | `sizes` | `md`, `lg` |
67
67
  | `states` | `default`, `filled`, `error`, `disabled` |
68
- | `tokens` | `--bh-border-width-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-subtle`, `--bh-icon-stroke-200`, `--bh-input-lg-height`, `--bh-input-md-height`, `--bh-select-field-gap`, `--bh-select-trigger-bg`, `--bh-select-trigger-bg-disabled`, `--bh-select-trigger-bg-soft`, `--bh-select-trigger-border`, `--bh-select-trigger-border-current`, `--bh-select-trigger-border-disabled`, `--bh-select-trigger-border-error`, `--bh-select-trigger-border-focus`, `--bh-select-trigger-icon-color`, `--bh-select-trigger-padding-x`, `--bh-select-trigger-radius`, `--bh-select-width`, `--bh-space-3xl-16`, `--bh-space-8xl-48`, `--bh-space-sm-6`, `--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-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`, `--shadow-component-default`, `--shadow-select-danger-focus-ring`, `--shadow-select-focus-ring`, `--shadow-select-trigger` |
68
+ | `tokens` | `--bh-border-width-default`, `--bh-content-danger-default`, `--bh-content-default`, `--bh-content-disabled`, `--bh-content-subtle`, `--bh-icon-stroke-200`, `--bh-input-lg-height`, `--bh-input-md-height`, `--bh-select-field-gap`, `--bh-select-trigger-bg`, `--bh-select-trigger-bg-disabled`, `--bh-select-trigger-bg-soft`, `--bh-select-trigger-border`, `--bh-select-trigger-border-current`, `--bh-select-trigger-border-disabled`, `--bh-select-trigger-border-error`, `--bh-select-trigger-border-focus`, `--bh-select-trigger-icon-color`, `--bh-select-trigger-padding-x`, `--bh-select-trigger-radius`, `--bh-select-width`, `--bh-space-3xl-16`, `--bh-space-8xl-48`, `--bh-space-sm-6`, `--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-xs-regular-font-size`, `--bh-text-body-xs-regular-font-weight`, `--bh-text-body-xs-regular-letter-spacing`, `--bh-text-body-xs-regular-line-height`, `--elevation-component-default`, `--elevation-select-danger-focus-ring`, `--elevation-select-focus-ring`, `--elevation-select-trigger` |
69
69
  | `variants` | `default`, `soft` |
70
70
  <!-- registry-contract:end -->