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,23 +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.
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.
@@ -1,73 +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.
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.
@@ -1,21 +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.
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.
@@ -1,69 +1,74 @@
1
- # Icons
2
-
3
- The interactive icon explorer is available in the app under the `Icons` section.
4
-
5
- ## Recommendation Posture
6
-
7
- Start the decision with five serious candidates:
8
-
9
- - `Lucide`: best default for modern product UI, especially if we want light, consistent, stroke-based icons.
10
- - `Tabler Icons`: best coverage-first option. It has a huge set, outline/fill coverage, and a familiar 24px grid.
11
- - `Material Symbols`: best if we want Google-style recognizability and many built-in style axes.
12
- - `Radix Icons`: best for very dense component UI where 15px icons need to stay crisp.
13
- - `Phosphor`: best if we want expressive weight control, including thin, bold, fill, and duotone variants.
14
-
15
- Keep `Simple Icons` as a separate brand-logo source. It should not be the primary UI icon family.
16
-
17
- ## Packs To Review
18
-
19
- | Pack | Prefix | License | Best for | Variants to compare |
20
- | --- | --- | --- | --- | --- |
21
- | Google Material Symbols | `material-symbols` | Apache-2.0 | Google-style UI, broad coverage | Regular, Rounded, Sharp, Outline, Outline Rounded, Outline Sharp |
22
- | Google Material Icons Classic | `ic` | Apache-2.0 | Existing Material Icons familiarity | Filled/Baseline, Outlined, Rounded, Sharp, Two tone |
23
- | Material Design Icons by Pictogrammers | `mdi` | Apache-2.0 | Maximum utility coverage | Single broad style |
24
- | Radix Icons | `radix-icons` | MIT | Dense controls, primitives, menus | Single 15px style |
25
- | Lucide | `lucide` | ISC | Clean SaaS/product UI | Single outline style |
26
- | Heroicons | `heroicons` | MIT | Tailwind-friendly apps | Outline 24, Solid 24, Solid 20, Solid 16 |
27
- | Tabler Icons | `tabler` | MIT | Broad app coverage | Outline, filled where available |
28
- | Phosphor | `ph` | MIT | Adjustable visual tone | Thin, Light, Regular, Bold, Fill, Duotone |
29
- | Remix Icon | `ri` | Apache-2.0 | Neutral line/fill system icons | Line, Fill |
30
- | Bootstrap Icons | `bi` | MIT | Bootstrap-adjacent apps | Mixed outline/fill names |
31
- | Fluent UI System Icons | `fluent` | MIT | Microsoft-like UI language | Regular, Filled |
32
- | Carbon Icons | `carbon` | Apache-2.0 | Enterprise/data tools | Fixed source sizes in packages |
33
- | Ant Design Icons | `ant-design` | MIT | Enterprise React products | Outlined, Filled, TwoTone |
34
- | Octicons | `octicon` | MIT | Developer tools, GitHub-like UI | 16px and 24px source sizes |
35
- | Feather Icons | `feather` | MIT | Minimal legacy outline style | Single outline style |
36
- | Iconoir | `iconoir` | MIT | Broad modern outline set | Single outline style |
37
- | Flowbite Icons | `flowbite` | MIT | Tailwind/Flowbite apps | Outline, Solid |
38
- | Ionicons | `ion` | MIT | Mobile/app UI | Outline, Filled, Sharp |
39
- | Simple Icons | `simple-icons` | CC0-1.0 | Brand logos only | Single-color brand marks |
40
-
41
- ## Decision Criteria
42
-
43
- - Button icon clarity at 16px and 20px.
44
- - Menu, dropdown, and table icon legibility in dense rows.
45
- - Visual match with `default`, `rounded`, and `sharp` appearances.
46
- - Variant usefulness: filled states, two-tone states, sharp geometry, or rounded geometry.
47
- - Coverage for navigation, data, files, users, settings, alerts, billing, integrations, and brand logos.
48
- - Licensing and attribution obligations. Keep source license notices in the project when redistributing SVG/source files.
49
-
50
- ## Sources
51
-
52
- - Google Material Icons repository: https://github.com/google/material-design-icons
53
- - Iconify collection API: https://iconify.design/docs/api/collection.html
54
- - Radix Icons: https://github.com/radix-ui/icons
55
- - Lucide: https://github.com/lucide-icons/lucide
56
- - Heroicons: https://heroicons.com
57
- - Tabler Icons: https://github.com/tabler/tabler-icons
58
- - Phosphor Icons: https://github.com/phosphor-icons/core
59
- - Remix Icon: https://www.remixicon.com
60
- - Bootstrap Icons: https://icons.getbootstrap.com
61
- - Fluent UI System Icons: https://github.com/microsoft/fluentui-system-icons
62
- - Carbon Icons: https://carbondesignsystem.com/elements/icons/code
63
- - Ant Design Icons: https://www.npmjs.com/package/@ant-design/icons
64
- - Octicons: https://primer.github.io/design/components/icon
65
- - Feather Icons: https://github.com/feathericons/feather
66
- - Iconoir: https://github.com/iconoir-icons/iconoir
67
- - Flowbite Icons: https://flowbite.com/icons
68
- - Ionicons: https://github.com/ionic-team/ionicons
69
- - Simple Icons: https://github.com/simple-icons/simple-icons
1
+ # Icons
2
+
3
+ The interactive icon explorer is available in the app under the `Icons` section.
4
+
5
+ ## Recommendation Posture
6
+
7
+ Start the decision with five serious candidates:
8
+
9
+ - `Lucide`: best default for modern product UI, especially if we want light, consistent, stroke-based icons.
10
+ - `Tabler Icons`: best coverage-first option. It has a huge set, outline/fill coverage, and a familiar 24px grid.
11
+ - `Material Symbols`: best if we want Google-style recognizability and many built-in style axes.
12
+ - `Radix Icons`: best for very dense component UI where 15px icons need to stay crisp.
13
+ - `Phosphor`: best if we want expressive weight control, including thin, bold, fill, and duotone variants.
14
+
15
+ Keep `Simple Icons` as a separate brand-logo source. It should not be the primary UI icon family.
16
+
17
+ ## Packs To Review
18
+
19
+ | Pack | Prefix | License | Best for | Variants to compare |
20
+ | --- | --- | --- | --- | --- |
21
+ | Google Material Symbols | `material-symbols` | Apache-2.0 | Google-style UI, broad coverage | Regular, Rounded, Sharp, Outline, Outline Rounded, Outline Sharp |
22
+ | Google Material Icons Classic | `ic` | Apache-2.0 | Existing Material Icons familiarity | Filled/Baseline, Outlined, Rounded, Sharp, Two tone |
23
+ | Material Design Icons by Pictogrammers | `mdi` | Apache-2.0 | Maximum utility coverage | Single broad style |
24
+ | Radix Icons | `radix-icons` | MIT | Dense controls, primitives, menus | Single 15px style |
25
+ | Lucide | `lucide` | ISC | Clean SaaS/product UI | Single outline style |
26
+ | Heroicons | `heroicons` | MIT | Tailwind-friendly apps | Outline 24, Solid 24, Solid 20, Solid 16 |
27
+ | Tabler Icons | `tabler` | MIT | Broad app coverage | Outline, filled where available |
28
+ | Phosphor | `ph` | MIT | Adjustable visual tone | Thin, Light, Regular, Bold, Fill, Duotone |
29
+ | Remix Icon | `ri` | Apache-2.0 | Neutral line/fill system icons | Line, Fill |
30
+ | Bootstrap Icons | `bi` | MIT | Bootstrap-adjacent apps | Mixed outline/fill names |
31
+ | Fluent UI System Icons | `fluent` | MIT | Microsoft-like UI language | Regular, Filled |
32
+ | Carbon Icons | `carbon` | Apache-2.0 | Enterprise/data tools | Fixed source sizes in packages |
33
+ | Ant Design Icons | `ant-design` | MIT | Enterprise React products | Outlined, Filled, TwoTone |
34
+ | Octicons | `octicon` | MIT | Developer tools, GitHub-like UI | 16px and 24px source sizes |
35
+ | Feather Icons | `feather` | MIT | Minimal legacy outline style | Single outline style |
36
+ | Iconoir | `iconoir` | MIT | Broad modern outline set | Single outline style |
37
+ | Flowbite Icons | `flowbite` | MIT | Tailwind/Flowbite apps | Outline, Solid |
38
+ | Ionicons | `ion` | MIT | Mobile/app UI | Outline, Filled, Sharp |
39
+ | Simple Icons | `simple-icons` | CC0-1.0 | Brand logos only | Single-color brand marks |
40
+
41
+ ## Decision Criteria
42
+
43
+ - Default UI glyph clarity at 18px, with the glyph centered in a 20px layout slot.
44
+ - Small-control icon clarity at 16px without promoting those intentionally compact glyphs to the default size.
45
+ - Menu, dropdown, and table icon legibility in dense rows.
46
+ - Visual match with `default`, `rounded`, and `sharp` appearances.
47
+ - Variant usefulness: filled states, two-tone states, sharp geometry, or rounded geometry.
48
+ - Coverage for navigation, data, files, users, settings, alerts, billing, integrations, and brand logos.
49
+ - Licensing and attribution obligations. Keep source license notices in the project when redistributing SVG/source files.
50
+
51
+ ## Default Geometry Contract
52
+
53
+ Default UI icons use `--bh-icon-size-default` (`18px`) inside `--bh-icon-slot-size-default` (`20px`). The resulting `--bh-icon-slot-inset-default` is `1px` on each side. Components must preserve that slot so switching from the former 20px glyph does not change alignment, gaps, or control dimensions. Intentional 12px, 16px, 24px, brand-logo, avatar, spinner, and control-indicator sizes remain component-specific.
54
+
55
+ ## Sources
56
+
57
+ - Google Material Icons repository: https://github.com/google/material-design-icons
58
+ - Iconify collection API: https://iconify.design/docs/api/collection.html
59
+ - Radix Icons: https://github.com/radix-ui/icons
60
+ - Lucide: https://github.com/lucide-icons/lucide
61
+ - Heroicons: https://heroicons.com
62
+ - Tabler Icons: https://github.com/tabler/tabler-icons
63
+ - Phosphor Icons: https://github.com/phosphor-icons/core
64
+ - Remix Icon: https://www.remixicon.com
65
+ - Bootstrap Icons: https://icons.getbootstrap.com
66
+ - Fluent UI System Icons: https://github.com/microsoft/fluentui-system-icons
67
+ - Carbon Icons: https://carbondesignsystem.com/elements/icons/code
68
+ - Ant Design Icons: https://www.npmjs.com/package/@ant-design/icons
69
+ - Octicons: https://primer.github.io/design/components/icon
70
+ - Feather Icons: https://github.com/feathericons/feather
71
+ - Iconoir: https://github.com/iconoir-icons/iconoir
72
+ - Flowbite Icons: https://flowbite.com/icons
73
+ - Ionicons: https://github.com/ionic-team/ionicons
74
+ - Simple Icons: https://github.com/simple-icons/simple-icons
@@ -1,68 +1,70 @@
1
- # Installation
2
-
3
- ## Requirements
4
-
5
- Banhaten installs source into a React 18.2/19 project using Tailwind CSS 4. Use Node 18.18 or newer.
6
-
7
- ```bash
8
- npx banhaten init
9
- npx banhaten add button input select
10
- ```
11
-
12
- Run the package-manager command printed by the CLI. It detects npm, pnpm, Yarn, and Bun from `packageManager` or lockfiles.
13
-
14
- Dependency declarations are validated with npm-compatible semantic-version
15
- ranges. A consumer range is kept only when every version it allows satisfies the
16
- Banhaten requirement. If the Banhaten range is wholly contained by a broader
17
- consumer range, the CLI safely narrows the declaration in its existing package
18
- section, updates `package.json`, and prints an install command so the package
19
- manager can reconcile its lockfile. Partial overlaps, disjoint ranges, mutable
20
- tags, workspace protocols, aliases, Git URLs, and local file specs fail without
21
- writing. Banhaten deliberately does not treat a current lockfile resolution as a
22
- durable compatibility guarantee. When the manifest is already safe, the CLI also
23
- checks package versions inside the target project or declared workspace boundary.
24
- For npm lockfiles v2 and v3 it verifies the importer declarations and exact locked
25
- resolutions; stale, missing, incompatible, or opaque lock state keeps the install
26
- action visible. Machine-readable output exposes the same
27
- `{ required, command, cwd }` state, including the project or workspace directory
28
- where the command must run.
29
-
30
- ## Vite
31
-
32
- Before writing, the CLI resolves a canonical install plan from
33
- `banhaten.config.json`, the TypeScript `@/*` path, and the Vite `@` alias. If
34
- TypeScript and Vite agree, that root is used even when another `src` directory
35
- exists. If only one side declares the alias, the CLI mirrors it to the other.
36
- Conflicting roots, multi-target TypeScript paths, destination-overlapping aliases,
37
- inherited TypeScript aliases without local `baseUrl`/`paths`, and Vite aliases
38
- that cannot be inspected statically fail without changing the project. When a
39
- supported Vite config exists, `init` also adds the Tailwind Vite plugin while
40
- preserving its existing structure.
41
-
42
- CLI commands use strict schemas. Unknown or duplicate flags, missing values, and
43
- unexpected positional arguments are rejected before project discovery. The
44
- install receipt pins the resolved destinations; changing roots later requires
45
- moving or removing the old generated files and receipt first.
46
-
47
- ## Next.js and other frameworks
48
-
49
- Without Vite, the CLI installs Tailwind and writes the configured global stylesheet, aliases, `cn` utility, and direction hook. Import the generated global stylesheet from the framework root layout and ensure the `@/*` TypeScript alias resolves to the source directory.
50
-
51
- ## Fonts and direction
52
-
53
- The generated stylesheet imports Inter weights 400–700 and IBM Plex Sans Arabic weights 400–700. Set document language and direction at the application boundary:
54
-
55
- ```tsx
56
- <html lang="ar" dir="rtl" data-theme="blue" data-radius="default">
57
- ```
58
-
59
- Wrap server-rendered component trees in `DirectionProvider` when request data already determines the direction; this keeps the first server and client snapshots identical. It is also the boundary for nested surfaces that differ from the document. Without it, components hydrate from a stable LTR snapshot and then synchronize from the document through one shared observer.
60
-
61
- ## Updating safely
62
-
63
- ```bash
64
- npx banhaten diff
65
- npx banhaten update
66
- ```
67
-
68
- The receipt records generated hashes. Unmodified files update automatically. Locally modified files and token blocks stop without writing; pass `--force` only after reviewing the unified diff. Put product overrides outside the marked token block and product composition in wrapper components.
1
+ # Installation
2
+
3
+ ## Requirements
4
+
5
+ Banhaten installs source into a React 18.2/19 project using Tailwind CSS 4. Use Node 18.18 or newer.
6
+
7
+ ```bash
8
+ npx banhaten init
9
+ npx banhaten add button input select
10
+ ```
11
+
12
+ Run the package-manager command printed by the CLI. It detects npm, pnpm, Yarn, and Bun from `packageManager` or lockfiles.
13
+
14
+ Dependency declarations are validated with npm-compatible semantic-version
15
+ ranges. A consumer range is kept only when every version it allows satisfies the
16
+ Banhaten requirement. If the Banhaten range is wholly contained by a broader
17
+ consumer range, the CLI safely narrows the declaration in its existing package
18
+ section, updates `package.json`, and prints an install command so the package
19
+ manager can reconcile its lockfile. Partial overlaps, disjoint ranges, mutable
20
+ tags, workspace protocols, aliases, Git URLs, and local file specs fail without
21
+ writing. Banhaten deliberately does not treat a current lockfile resolution as a
22
+ durable compatibility guarantee. When the manifest is already safe, the CLI also
23
+ checks package versions inside the target project or declared workspace boundary.
24
+ For npm lockfiles v2 and v3 it verifies the importer declarations and exact locked
25
+ resolutions; stale, missing, incompatible, or opaque lock state keeps the install
26
+ action visible. Machine-readable output exposes the same
27
+ `{ required, command, cwd }` state, including the project or workspace directory
28
+ where the command must run.
29
+
30
+ ## Vite
31
+
32
+ Before writing, the CLI resolves a canonical install plan from
33
+ `banhaten.config.json`, the TypeScript `@/*` path, and the Vite `@` alias. If
34
+ TypeScript and Vite agree, that root is used even when another `src` directory
35
+ exists. If only one side declares the alias, the CLI mirrors it to the other.
36
+ Conflicting roots, multi-target TypeScript paths, destination-overlapping aliases,
37
+ inherited TypeScript aliases without local `baseUrl`/`paths`, and Vite aliases
38
+ that cannot be inspected statically fail without changing the project. When a
39
+ supported Vite config exists, `init` also adds the Tailwind Vite plugin while
40
+ preserving its existing structure.
41
+
42
+ CLI commands use strict schemas. Unknown or duplicate flags, missing values, and
43
+ unexpected positional arguments are rejected before project discovery. The
44
+ install receipt pins the resolved destinations; changing roots later requires
45
+ moving or removing the old generated files and receipt first.
46
+
47
+ ## Next.js and other frameworks
48
+
49
+ Without Vite, the CLI installs Tailwind and writes the configured global stylesheet, aliases, `cn` utility, and direction hook. Import the generated global stylesheet from the framework root layout and ensure the `@/*` TypeScript alias resolves to the source directory.
50
+
51
+ ## Fonts and direction
52
+
53
+ The generated stylesheet imports Inter weights 400–700 and IBM Plex Sans Arabic weights 400–700. Set document language and direction at the application boundary:
54
+
55
+ ```tsx
56
+ <html lang="ar" dir="rtl" data-theme="gray" data-radius="default">
57
+ ```
58
+
59
+ Wrap server-rendered component trees in `DirectionProvider` when request data already determines the direction; this keeps the first server and client snapshots identical. It is also the boundary for nested surfaces that differ from the document. Without it, components hydrate from a stable LTR snapshot and then synchronize from the document through one shared observer.
60
+
61
+ ## Updating safely
62
+
63
+ ```bash
64
+ npx banhaten diff
65
+ npx banhaten update
66
+ ```
67
+
68
+ The receipt records generated hashes. Unmodified files update automatically. Locally modified files and token blocks stop without writing; pass `--force` only after reviewing the unified diff. Put product overrides outside the marked token block and product composition in wrapper components.
69
+
70
+ The CLI also checks the original contents of every write target and the files used for ownership checks and merges before and after staging. An intervening edit, creation, or deletion aborts the plan, even with `--force`. Re-run the command after concurrent edits have finished.