banhaten 0.1.2 → 0.2.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 (365) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/CONTRIBUTING.md +44 -0
  3. package/README.md +145 -328
  4. package/SECURITY.md +15 -0
  5. package/banhaten.config.example.json +1 -3
  6. package/docs/design-system/README.md +20 -0
  7. package/docs/design-system/adoption-quality-remediation.md +87 -0
  8. package/docs/design-system/agent-usage.md +13 -0
  9. package/docs/design-system/appearance-presets.md +189 -0
  10. package/docs/design-system/appearances/default.md +94 -0
  11. package/docs/design-system/appearances/rounded.md +95 -0
  12. package/docs/design-system/appearances/sharp.md +95 -0
  13. package/docs/design-system/component-docs-pattern.md +81 -0
  14. package/docs/design-system/component-showcase-consistency-report.md +217 -0
  15. package/docs/design-system/component-token-consistency-audit.md +173 -0
  16. package/docs/design-system/components/README.md +75 -0
  17. package/docs/design-system/components/accordion.md +67 -0
  18. package/docs/design-system/components/activity-feed.md +106 -0
  19. package/docs/design-system/components/alert-dialog.md +87 -0
  20. package/docs/design-system/components/alert.md +111 -0
  21. package/docs/design-system/components/aspect-ratio.md +59 -0
  22. package/docs/design-system/components/attribute.md +103 -0
  23. package/docs/design-system/components/autocomplete.md +93 -0
  24. package/docs/design-system/components/avatar.md +70 -0
  25. package/docs/design-system/components/badge.md +72 -0
  26. package/docs/design-system/components/banner.md +99 -0
  27. package/docs/design-system/components/breadcrumbs.md +188 -0
  28. package/docs/design-system/components/button-group.md +117 -0
  29. package/docs/design-system/components/button.md +95 -0
  30. package/docs/design-system/components/card.md +95 -0
  31. package/docs/design-system/components/carousel.md +61 -0
  32. package/docs/design-system/components/catalog-components.md +59 -0
  33. package/docs/design-system/components/chart.md +58 -0
  34. package/docs/design-system/components/checkbox.md +68 -0
  35. package/docs/design-system/components/collapsible.md +63 -0
  36. package/docs/design-system/components/command.md +75 -0
  37. package/docs/design-system/components/context-menu.md +59 -0
  38. package/docs/design-system/components/date-picker.md +97 -0
  39. package/docs/design-system/components/divider.md +117 -0
  40. package/docs/design-system/components/empty-state.md +72 -0
  41. package/docs/design-system/components/field.md +86 -0
  42. package/docs/design-system/components/file-upload.md +199 -0
  43. package/docs/design-system/components/hover-card.md +61 -0
  44. package/docs/design-system/components/icons.md +48 -0
  45. package/docs/design-system/components/input-group.md +73 -0
  46. package/docs/design-system/components/input-otp.md +73 -0
  47. package/docs/design-system/components/input.md +84 -0
  48. package/docs/design-system/components/item.md +72 -0
  49. package/docs/design-system/components/kbd.md +62 -0
  50. package/docs/design-system/components/label.md +64 -0
  51. package/docs/design-system/components/menu.md +76 -0
  52. package/docs/design-system/components/menubar.md +60 -0
  53. package/docs/design-system/components/modal.md +119 -0
  54. package/docs/design-system/components/native-select.md +70 -0
  55. package/docs/design-system/components/navigation-menu.md +63 -0
  56. package/docs/design-system/components/onboarding-step-list-item.md +94 -0
  57. package/docs/design-system/components/page-header.md +98 -0
  58. package/docs/design-system/components/pagination.md +71 -0
  59. package/docs/design-system/components/popover.md +77 -0
  60. package/docs/design-system/components/progress-slider.md +66 -0
  61. package/docs/design-system/components/progress.md +92 -0
  62. package/docs/design-system/components/radio-card.md +65 -0
  63. package/docs/design-system/components/radio-group.md +72 -0
  64. package/docs/design-system/components/resizable.md +57 -0
  65. package/docs/design-system/components/scroll-area.md +60 -0
  66. package/docs/design-system/components/segmented-control.md +71 -0
  67. package/docs/design-system/components/select.md +87 -0
  68. package/docs/design-system/components/sheet.md +82 -0
  69. package/docs/design-system/components/sidebar.md +83 -0
  70. package/docs/design-system/components/skeleton.md +91 -0
  71. package/docs/design-system/components/slideout.md +77 -0
  72. package/docs/design-system/components/slider.md +81 -0
  73. package/docs/design-system/components/social-button.md +65 -0
  74. package/docs/design-system/components/spinner.md +77 -0
  75. package/docs/design-system/components/steps.md +77 -0
  76. package/docs/design-system/components/table.md +411 -0
  77. package/docs/design-system/components/tabs.md +69 -0
  78. package/docs/design-system/components/tag.md +95 -0
  79. package/docs/design-system/components/textarea.md +64 -0
  80. package/docs/design-system/components/timeline.md +95 -0
  81. package/docs/design-system/components/toast.md +73 -0
  82. package/docs/design-system/components/toggle.md +96 -0
  83. package/docs/design-system/components/toolbar.md +105 -0
  84. package/docs/design-system/components/tooltip.md +107 -0
  85. package/docs/design-system/components/typography.md +18 -0
  86. package/docs/design-system/density-and-elevation.md +44 -0
  87. package/docs/design-system/design-system-test-missing-items.md +368 -0
  88. package/docs/design-system/direction-and-localization.md +23 -0
  89. package/docs/design-system/form-recipes.md +73 -0
  90. package/docs/design-system/gap-promotion-policy.md +21 -0
  91. package/docs/design-system/gap-promotion-report.md +166 -0
  92. package/docs/design-system/icons.md +69 -0
  93. package/docs/design-system/installation.md +68 -0
  94. package/docs/design-system/launch-comparison-shadcn.md +98 -0
  95. package/docs/design-system/registry-and-cli.md +64 -0
  96. package/docs/design-system/release-policy.md +30 -0
  97. package/docs/design-system/roadmap.md +14 -0
  98. package/docs/design-system/support-matrix.md +23 -0
  99. package/docs/design-system/tabs.md +53 -0
  100. package/docs/design-system/token-governance.md +60 -0
  101. package/package.json +97 -65
  102. package/registry/component-contract.json +40 -0
  103. package/registry/components/alert-dialog.tsx +297 -0
  104. package/registry/components/alert.tsx +86 -65
  105. package/registry/components/aspect-ratio.tsx +30 -0
  106. package/registry/components/autocomplete.tsx +23 -9
  107. package/registry/components/avatar.tsx +7 -7
  108. package/registry/components/badge.tsx +1 -1
  109. package/registry/components/button-group.tsx +321 -4
  110. package/registry/components/button.tsx +38 -17
  111. package/registry/components/card.tsx +68 -59
  112. package/registry/components/carousel.tsx +282 -0
  113. package/registry/components/chart.tsx +203 -0
  114. package/registry/components/checkbox.tsx +3 -3
  115. package/registry/components/collapsible.tsx +69 -0
  116. package/registry/components/command.tsx +174 -0
  117. package/registry/components/context-menu.tsx +236 -0
  118. package/registry/components/date-picker.tsx +246 -105
  119. package/registry/components/expanded/ActivityFeed.tsx +6 -15
  120. package/registry/components/expanded/Banner.tsx +3 -3
  121. package/registry/components/expanded/Breadcrumbs.tsx +5 -5
  122. package/registry/components/expanded/CatalogComponentsShowcase.tsx +13 -13
  123. package/registry/components/expanded/CatalogDivider.tsx +1 -1
  124. package/registry/components/expanded/EmptyState.tsx +1 -1
  125. package/registry/components/expanded/FileUpload.tsx +9 -2
  126. package/registry/components/expanded/OnboardingStepListItem.tsx +2 -4
  127. package/registry/components/expanded/PageHeader.tsx +14 -14
  128. package/registry/components/expanded/Slideout.tsx +15 -415
  129. package/registry/components/expanded/Steps.tsx +4 -4
  130. package/registry/components/expanded/Table.tsx +116 -69
  131. package/registry/components/expanded/Timeline.tsx +3 -3
  132. package/registry/components/expanded/activityFeed.css +1 -1
  133. package/registry/components/expanded/breadcrumbs.css +139 -139
  134. package/registry/components/expanded/catalogComponentsShowcase.css +83 -83
  135. package/registry/components/expanded/divider.css +1 -1
  136. package/registry/components/expanded/emptyState.css +1 -1
  137. package/registry/components/expanded/fileUpload.css +6 -6
  138. package/registry/components/expanded/slideout.css +9 -685
  139. package/registry/components/expanded/steps.css +274 -274
  140. package/registry/components/expanded/table.css +2 -2
  141. package/registry/components/expanded/timeline.css +264 -264
  142. package/registry/components/field.tsx +230 -0
  143. package/registry/components/hover-card.tsx +48 -0
  144. package/registry/components/input-content.ts +1 -0
  145. package/registry/components/input-group.tsx +130 -0
  146. package/registry/components/input-otp.tsx +13 -3
  147. package/registry/components/input.tsx +70 -45
  148. package/registry/components/item.tsx +189 -0
  149. package/registry/components/kbd.tsx +151 -0
  150. package/registry/components/label.tsx +78 -0
  151. package/registry/components/menu.tsx +34 -246
  152. package/registry/components/menubar.tsx +226 -0
  153. package/registry/components/modal.tsx +216 -143
  154. package/registry/components/native-select.tsx +205 -0
  155. package/registry/components/navigation-menu.tsx +171 -0
  156. package/registry/components/pagination.tsx +80 -58
  157. package/registry/components/popover.tsx +162 -664
  158. package/registry/components/radio-card.tsx +116 -87
  159. package/registry/components/radio-group.tsx +1 -1
  160. package/registry/components/resizable.tsx +74 -0
  161. package/registry/components/scroll-area.tsx +67 -0
  162. package/registry/components/segmented-control.tsx +87 -0
  163. package/registry/components/select-content.tsx +2 -2
  164. package/registry/components/select.tsx +54 -20
  165. package/registry/components/sheet.tsx +305 -0
  166. package/registry/components/sidebar.tsx +352 -0
  167. package/registry/components/skeleton.css +0 -3
  168. package/registry/components/social-button.tsx +116 -30
  169. package/registry/components/spinner.tsx +18 -55
  170. package/registry/components/{expanded/tabs.css → tabs.css} +127 -106
  171. package/registry/components/tabs.tsx +246 -0
  172. package/registry/components/tag.tsx +2 -2
  173. package/registry/components/textarea.tsx +4 -4
  174. package/registry/components/toast.tsx +136 -0
  175. package/registry/components/toggle.tsx +2 -2
  176. package/registry/components/toolbar.tsx +89 -17
  177. package/registry/components/tooltip.tsx +1 -1
  178. package/registry/examples/alert-demo.tsx +25 -5
  179. package/registry/examples/alert-dialog-demo.tsx +42 -0
  180. package/registry/examples/aspect-ratio-demo.tsx +11 -0
  181. package/registry/examples/attribute-demo.tsx +1 -1
  182. package/registry/examples/autocomplete-demo.tsx +3 -3
  183. package/registry/examples/avatar-demo.tsx +7 -7
  184. package/registry/examples/badge-demo.tsx +1 -1
  185. package/registry/examples/button-demo.tsx +6 -6
  186. package/registry/examples/button-group-demo.tsx +23 -2
  187. package/registry/examples/card-demo.tsx +46 -8
  188. package/registry/examples/carousel-demo.tsx +43 -0
  189. package/registry/examples/chart-demo.tsx +33 -0
  190. package/registry/examples/checkbox-demo.tsx +5 -5
  191. package/registry/examples/collapsible-demo.tsx +16 -0
  192. package/registry/examples/collection-filter-bar-demo.tsx +135 -0
  193. package/registry/examples/command-demo.tsx +42 -0
  194. package/registry/examples/{expanded/command-bar-demo.tsx → command-palette-demo.tsx} +5 -15
  195. package/registry/examples/context-menu-demo.tsx +29 -0
  196. package/registry/examples/control-density-contract-demo.tsx +61 -0
  197. package/registry/examples/date-picker-demo.tsx +12 -12
  198. package/registry/examples/divider-demo.tsx +3 -3
  199. package/registry/examples/expanded/banner-demo.tsx +1 -1
  200. package/registry/examples/expanded/breadcrumbs-demo.tsx +1 -1
  201. package/registry/examples/expanded/empty-state-demo.tsx +1 -1
  202. package/registry/examples/expanded/file-upload-demo.tsx +1 -1
  203. package/registry/examples/expanded/onboarding-step-demo.tsx +1 -1
  204. package/registry/examples/expanded/slideout-demo.tsx +2 -2
  205. package/registry/examples/expanded/steps-demo.tsx +1 -1
  206. package/registry/examples/expanded/tabs-demo.tsx +2 -2
  207. package/registry/examples/expanded/timeline-demo.tsx +1 -1
  208. package/registry/examples/field-demo.tsx +51 -0
  209. package/registry/examples/hover-card-demo.tsx +23 -0
  210. package/registry/examples/input-demo.tsx +6 -6
  211. package/registry/examples/input-group-demo.tsx +16 -0
  212. package/registry/examples/input-otp-demo.tsx +4 -4
  213. package/registry/examples/item-demo.tsx +46 -0
  214. package/registry/examples/kbd-demo.tsx +11 -0
  215. package/registry/examples/label-demo.tsx +20 -0
  216. package/registry/examples/menu-demo.tsx +1 -1
  217. package/registry/examples/menubar-demo.tsx +34 -0
  218. package/registry/examples/modal-demo.tsx +67 -9
  219. package/registry/examples/native-select-demo.tsx +16 -0
  220. package/registry/examples/navigation-menu-demo.tsx +29 -0
  221. package/registry/examples/pagination-demo.tsx +6 -3
  222. package/registry/examples/popover-demo.tsx +19 -19
  223. package/registry/examples/progress-demo.tsx +1 -1
  224. package/registry/examples/progress-slider-demo.tsx +1 -1
  225. package/registry/examples/radio-card-demo.tsx +4 -4
  226. package/registry/examples/radio-group-demo.tsx +2 -2
  227. package/registry/examples/resizable-demo.tsx +22 -0
  228. package/registry/examples/results-toolbar-demo.tsx +44 -0
  229. package/registry/examples/scroll-area-demo.tsx +15 -0
  230. package/registry/examples/segmented-control-demo.tsx +39 -0
  231. package/registry/examples/select-demo.tsx +1 -1
  232. package/registry/examples/sheet-demo.tsx +47 -0
  233. package/registry/examples/sidebar-demo.tsx +55 -0
  234. package/registry/examples/slider-demo.tsx +3 -3
  235. package/registry/examples/social-button-demo.tsx +18 -8
  236. package/registry/examples/spinner-demo.tsx +13 -13
  237. package/registry/examples/tabs-demo.tsx +13 -0
  238. package/registry/examples/tag-demo.tsx +1 -1
  239. package/registry/examples/textarea-demo.tsx +4 -4
  240. package/registry/examples/toast-demo.tsx +35 -0
  241. package/registry/examples/toggle-demo.tsx +6 -6
  242. package/registry/examples/tooltip-demo.tsx +4 -4
  243. package/registry/guidance/USAGE.md +27 -0
  244. package/registry/hooks/use-direction.ts +193 -13
  245. package/registry/index.json +6010 -432
  246. package/registry/styles/globals.css +3112 -4690
  247. package/registry.json +1582 -0
  248. package/schema/config.schema.json +51 -0
  249. package/schema/registry.schema.json +190 -0
  250. package/schema/tokens.schema.json +163 -0
  251. package/src/cli/command-line.js +194 -0
  252. package/src/cli/config-editors.js +9 -0
  253. package/src/cli/doctor.js +399 -0
  254. package/src/cli/file-transaction.js +295 -0
  255. package/src/cli/global-css.js +153 -0
  256. package/src/cli/index.js +639 -1391
  257. package/src/cli/install-plan.js +592 -0
  258. package/src/cli/install-receipt.js +171 -0
  259. package/src/cli/jsonc.js +203 -0
  260. package/src/cli/package-install-state.js +254 -0
  261. package/src/cli/package-manager.js +238 -0
  262. package/src/cli/package-plan.js +185 -0
  263. package/src/cli/package-version.js +97 -0
  264. package/src/cli/registry-query.js +207 -0
  265. package/src/cli/reporting.js +55 -0
  266. package/src/cli/schema-validation.js +19 -0
  267. package/src/cli/source-scanner.js +686 -0
  268. package/src/cli/vite-config.js +478 -0
  269. package/tokens/banhaten.tokens.json +4313 -310
  270. package/registry/assets/avatars/avatar-02.jpg +0 -0
  271. package/registry/assets/avatars/avatar-03.jpg +0 -0
  272. package/registry/assets/avatars/avatar-04.jpg +0 -0
  273. package/registry/assets/avatars/avatar-05.jpg +0 -0
  274. package/registry/assets/avatars/avatar-06.jpg +0 -0
  275. package/registry/assets/avatars/avatar-07.jpg +0 -0
  276. package/registry/assets/avatars/avatar-08.jpg +0 -0
  277. package/registry/assets/avatars/avatar-09.jpg +0 -0
  278. package/registry/assets/avatars/avatar-10.jpg +0 -0
  279. package/registry/assets/avatars/avatar-11.jpg +0 -0
  280. package/registry/assets/avatars/avatar-12.jpg +0 -0
  281. package/registry/assets/avatars/avatar-13.jpg +0 -0
  282. package/registry/assets/avatars/avatar-14.jpg +0 -0
  283. package/registry/assets/avatars/avatar-15.jpg +0 -0
  284. package/registry/assets/avatars/avatar-16.jpg +0 -0
  285. package/registry/assets/avatars/avatar-17.jpg +0 -0
  286. package/registry/assets/avatars/avatar-18.jpg +0 -0
  287. package/registry/assets/avatars/avatar-19.jpg +0 -0
  288. package/registry/assets/avatars/avatar-20.jpg +0 -0
  289. package/registry/assets/avatars/avatar-21.jpg +0 -0
  290. package/registry/assets/avatars/avatar-22.jpg +0 -0
  291. package/registry/assets/avatars/avatar-23.jpg +0 -0
  292. package/registry/assets/avatars/avatar-24.jpg +0 -0
  293. package/registry/assets/avatars/avatar-25.jpg +0 -0
  294. package/registry/assets/avatars/avatar-26.jpg +0 -0
  295. package/registry/assets/avatars/avatar-27.jpg +0 -0
  296. package/registry/assets/avatars/avatar-28.jpg +0 -0
  297. package/registry/assets/avatars/avatar-29.jpg +0 -0
  298. package/registry/assets/avatars/avatar-30.jpg +0 -0
  299. package/registry/assets/avatars/avatar-31.jpg +0 -0
  300. package/registry/assets/avatars/avatar-32.jpg +0 -0
  301. package/registry/assets/avatars/avatar-33.jpg +0 -0
  302. package/registry/assets/avatars/avatar-34.jpg +0 -0
  303. package/registry/assets/avatars/avatar-35.jpg +0 -0
  304. package/registry/assets/image-assets.json +0 -744
  305. package/registry/assets/images/art-02.jpg +0 -0
  306. package/registry/assets/images/art-03.jpg +0 -0
  307. package/registry/assets/images/art-04.jpg +0 -0
  308. package/registry/assets/images/art-05.jpg +0 -0
  309. package/registry/assets/images/art-06.jpg +0 -0
  310. package/registry/assets/images/art-07.jpg +0 -0
  311. package/registry/assets/images/art-08.jpg +0 -0
  312. package/registry/assets/images/art-09.jpg +0 -0
  313. package/registry/assets/images/art-10.jpg +0 -0
  314. package/registry/assets/images/art-11.jpg +0 -0
  315. package/registry/assets/images/art-12.jpg +0 -0
  316. package/registry/assets/images/art-13.jpg +0 -0
  317. package/registry/assets/images/art-14.jpg +0 -0
  318. package/registry/assets/images/art-15.jpg +0 -0
  319. package/registry/assets/images/art-16.jpg +0 -0
  320. package/registry/assets/images/art-17.jpg +0 -0
  321. package/registry/assets/images/art-18.jpg +0 -0
  322. package/registry/assets/images/art-19.jpg +0 -0
  323. package/registry/assets/images/art-20.jpg +0 -0
  324. package/registry/assets/images/art-21.jpg +0 -0
  325. package/registry/assets/images/art-22.jpg +0 -0
  326. package/registry/assets/images/art-23.jpg +0 -0
  327. package/registry/assets/images/art-24.jpg +0 -0
  328. package/registry/assets/images/art-25.jpg +0 -0
  329. package/registry/assets/images/art-26.jpg +0 -0
  330. package/registry/assets/images/art-27.jpg +0 -0
  331. package/registry/assets/images/nature-01.jpg +0 -0
  332. package/registry/assets/images/nature-02.jpg +0 -0
  333. package/registry/assets/images/nature-03.jpg +0 -0
  334. package/registry/assets/images/nature-04.jpg +0 -0
  335. package/registry/assets/images/nature-05.jpg +0 -0
  336. package/registry/assets/images/nature-06.jpg +0 -0
  337. package/registry/assets/images/nature-07.jpg +0 -0
  338. package/registry/assets/images/nature-08.jpg +0 -0
  339. package/registry/assets/images/nature-09.jpg +0 -0
  340. package/registry/assets/images/nature-10.jpg +0 -0
  341. package/registry/assets/images/nature-11.jpg +0 -0
  342. package/registry/assets/images/nature-12.jpg +0 -0
  343. package/registry/assets/images/nature-13.jpg +0 -0
  344. package/registry/assets/images/nature-14.jpg +0 -0
  345. package/registry/assets/images/nature-15.jpg +0 -0
  346. package/registry/assets/images/nature-16.jpg +0 -0
  347. package/registry/assets/images/nature-17.jpg +0 -0
  348. package/registry/assets/images/nature-18.jpg +0 -0
  349. package/registry/assets/images/nature-19.jpg +0 -0
  350. package/registry/assets/images/nature-20.jpg +0 -0
  351. package/registry/components/expanded/BannerBoard.tsx +0 -225
  352. package/registry/components/expanded/CatalogTag.tsx +0 -85
  353. package/registry/components/expanded/CommandBar.tsx +0 -386
  354. package/registry/components/expanded/IconExplorer.tsx +0 -612
  355. package/registry/components/expanded/Tabs.tsx +0 -86
  356. package/registry/components/expanded/TimelineShowcase.tsx +0 -158
  357. package/registry/components/expanded/commandBar.css +0 -470
  358. package/registry/components/expanded/iconExplorer.css +0 -764
  359. package/registry/components/expanded/iconPacks.ts +0 -866
  360. package/registry/components/expanded/tag.css +0 -148
  361. package/registry/examples/expanded/icons-demo.tsx +0 -5
  362. package/tokens/Color mode.zip +0 -0
  363. package/tokens/Numbers.zip +0 -0
  364. package/tokens/Radius.zip +0 -0
  365. package/tokens/Theme.zip +0 -0
@@ -2,6 +2,7 @@ import * as React from "react"
2
2
  import { cva, type VariantProps } from "class-variance-authority"
3
3
  import { Building2Icon, CreditCardIcon, UserIcon } from "lucide-react"
4
4
 
5
+ import { useResolvedDirection, type Direction } from "@/hooks/use-direction"
5
6
  import { cn } from "@/lib/utils"
6
7
 
7
8
  type RadioCardType =
@@ -14,7 +15,7 @@ type RadioCardType =
14
15
  | "radio-label"
15
16
 
16
17
  type RadioCardState = "default" | "active" | "disabled"
17
- type RadioCardDirection = "ltr" | "rtl"
18
+ type RadioCardDirection = Direction
18
19
 
19
20
  const radioCardVariants = cva(
20
21
  [
@@ -69,91 +70,119 @@ type RadioCardProps = Omit<
69
70
  inputProps?: Omit<React.ComponentProps<"input">, "type">
70
71
  }
71
72
 
72
- function RadioCard({
73
- className,
74
- type = "with-icon",
75
- state = "default",
76
- direction = "ltr",
77
- checked,
78
- disabled,
79
- label,
80
- description,
81
- supportLabel,
82
- supportDescription,
83
- showDescription = true,
84
- showSupportItems = true,
85
- showSupportDescription = true,
86
- icon,
87
- media,
88
- inputProps,
89
- ...props
90
- }: RadioCardProps) {
91
- const hasControlledChecked =
92
- checked !== undefined || inputProps?.checked !== undefined
93
- const controlledChecked = checked ?? inputProps?.checked
94
- const inputChecked =
95
- controlledChecked ?? Boolean(inputProps?.defaultChecked)
96
- const inputReadOnly =
97
- inputProps?.readOnly ??
98
- (hasControlledChecked && inputProps?.onChange === undefined
99
- ? true
100
- : undefined)
101
- const isDisabled = disabled ?? inputProps?.disabled ?? state === "disabled"
102
- const visualState: RadioCardState = isDisabled
103
- ? "disabled"
104
- : inputChecked || state === "active"
105
- ? "active"
106
- : state ?? "default"
107
- const isRtl = direction === "rtl"
108
- const textLabel = label
109
- const textDescription = description
73
+ const RadioCard = React.forwardRef<HTMLLabelElement, RadioCardProps>(
74
+ function RadioCard(
75
+ {
76
+ className,
77
+ type = "with-icon",
78
+ state = "default",
79
+ direction,
80
+ dir,
81
+ checked,
82
+ disabled,
83
+ label,
84
+ description,
85
+ supportLabel,
86
+ supportDescription,
87
+ showDescription = true,
88
+ showSupportItems = true,
89
+ showSupportDescription = true,
90
+ icon,
91
+ media,
92
+ inputProps,
93
+ ...props
94
+ },
95
+ forwardedRef
96
+ ) {
97
+ const directionBoundaryRef = React.useRef<HTMLLabelElement | null>(null)
98
+ const explicitDirection =
99
+ direction ?? (dir === "ltr" || dir === "rtl" ? dir : undefined)
100
+ const resolvedDirection = useResolvedDirection(
101
+ explicitDirection,
102
+ directionBoundaryRef
103
+ )
104
+ const setDirectionBoundaryRef = React.useCallback(
105
+ (node: HTMLLabelElement | null) => {
106
+ directionBoundaryRef.current = node
107
+
108
+ if (typeof forwardedRef === "function") {
109
+ forwardedRef(node)
110
+ } else if (forwardedRef) {
111
+ forwardedRef.current = node
112
+ }
113
+ },
114
+ [forwardedRef]
115
+ )
116
+ const hasControlledChecked =
117
+ checked !== undefined || inputProps?.checked !== undefined
118
+ const controlledChecked = checked ?? inputProps?.checked
119
+ const inputChecked =
120
+ controlledChecked ?? Boolean(inputProps?.defaultChecked)
121
+ const inputReadOnly =
122
+ inputProps?.readOnly ??
123
+ (hasControlledChecked && inputProps?.onChange === undefined
124
+ ? true
125
+ : undefined)
126
+ const isDisabled = disabled ?? inputProps?.disabled ?? state === "disabled"
127
+ const visualState: RadioCardState = isDisabled
128
+ ? "disabled"
129
+ : inputChecked || state === "active"
130
+ ? "active"
131
+ : state ?? "default"
132
+ const isRtl = resolvedDirection === "rtl"
133
+ const textLabel = label
134
+ const textDescription = description
110
135
 
111
- return (
112
- <label
113
- data-slot="radio-card"
114
- data-state={visualState}
115
- data-type={type}
116
- data-direction={direction}
117
- {...props}
118
- dir="ltr"
119
- className={cn(radioCardVariants({ state: visualState }), className)}
120
- >
121
- <input
122
- aria-label={typeof textLabel === "string" ? textLabel : undefined}
123
- {...inputProps}
124
- checked={hasControlledChecked ? controlledChecked : undefined}
125
- className={cn("sr-only", inputProps?.className)}
126
- defaultChecked={hasControlledChecked ? undefined : inputProps?.defaultChecked}
127
- disabled={isDisabled}
128
- readOnly={inputReadOnly}
129
- type="radio"
130
- />
131
- <span
132
- data-slot="radio-card-layout"
133
- className={cn(
134
- "flex min-w-0 items-start [direction:ltr]",
135
- type === "radio-label" && "items-center",
136
- getCardGapClass(type, isRtl)
137
- )}
136
+ return (
137
+ <label
138
+ data-slot="radio-card"
139
+ data-state={visualState}
140
+ data-type={type}
141
+ {...props}
142
+ ref={setDirectionBoundaryRef}
143
+ data-direction={resolvedDirection}
144
+ dir={resolvedDirection}
145
+ className={cn(radioCardVariants({ state: visualState }), className)}
138
146
  >
139
- {renderRadioCardContent({
140
- type,
141
- direction,
142
- state: visualState,
143
- label: textLabel,
144
- description: textDescription,
145
- supportLabel,
146
- supportDescription,
147
- showDescription,
148
- showSupportItems,
149
- showSupportDescription,
150
- icon,
151
- media,
152
- })}
153
- </span>
154
- </label>
155
- )
156
- }
147
+ <input
148
+ aria-label={typeof textLabel === "string" ? textLabel : undefined}
149
+ {...inputProps}
150
+ checked={hasControlledChecked ? controlledChecked : undefined}
151
+ className={cn("sr-only", inputProps?.className)}
152
+ defaultChecked={
153
+ hasControlledChecked ? undefined : inputProps?.defaultChecked
154
+ }
155
+ disabled={isDisabled}
156
+ readOnly={inputReadOnly}
157
+ type="radio"
158
+ />
159
+ <span
160
+ data-slot="radio-card-layout"
161
+ className={cn(
162
+ "flex min-w-0 items-start [direction:ltr]",
163
+ type === "radio-label" && "items-center",
164
+ getCardGapClass(type, isRtl)
165
+ )}
166
+ >
167
+ {renderRadioCardContent({
168
+ type,
169
+ direction: resolvedDirection,
170
+ state: visualState,
171
+ label: textLabel,
172
+ description: textDescription,
173
+ supportLabel,
174
+ supportDescription,
175
+ showDescription,
176
+ showSupportItems,
177
+ showSupportDescription,
178
+ icon,
179
+ media,
180
+ })}
181
+ </span>
182
+ </label>
183
+ )
184
+ }
185
+ )
157
186
 
158
187
  function renderRadioCardContent({
159
188
  type,
@@ -564,7 +593,7 @@ function RadioCardUserIcon() {
564
593
  <UserIcon
565
594
  aria-hidden="true"
566
595
  className="size-[var(--bh-space-4xl-20)]"
567
- strokeWidth={2}
596
+ strokeWidth="var(--bh-icon-stroke-200)"
568
597
  />
569
598
  )
570
599
  }
@@ -578,7 +607,7 @@ function RadioCardPaymentIcon() {
578
607
  <CreditCardIcon
579
608
  aria-hidden="true"
580
609
  className="h-[var(--bh-radio-card-payment-logo-height)] w-[var(--bh-radio-card-payment-logo-width)]"
581
- strokeWidth={2}
610
+ strokeWidth="var(--bh-icon-stroke-200)"
582
611
  />
583
612
  </span>
584
613
  )
@@ -610,7 +639,7 @@ function RadioCardCompanyIcon({ disabled }: { disabled: boolean }) {
610
639
  <Building2Icon
611
640
  aria-hidden="true"
612
641
  className="size-[var(--bh-space-5xl-24)] text-[var(--bh-radio-card-company-mark-color)]"
613
- strokeWidth={1.8}
642
+ strokeWidth="var(--bh-icon-stroke-180)"
614
643
  />
615
644
  </span>
616
645
  )
@@ -100,7 +100,7 @@ const Radio = React.forwardRef<HTMLInputElement, RadioProps>(function Radio({
100
100
  ref={ref}
101
101
  type="radio"
102
102
  className={cn(
103
- "peer absolute inset-0 z-[var(--bh-z-raised)] m-0 size-full cursor-pointer appearance-none rounded-[var(--bh-radius-full)] opacity-0 outline-none disabled:cursor-not-allowed",
103
+ "peer absolute inset-0 z-[var(--bh-z-raised)] m-0 size-full cursor-pointer appearance-none rounded-[var(--bh-radius-full)] opacity-[var(--bh-opacity-0)] outline-none disabled:cursor-not-allowed",
104
104
  inputClassName
105
105
  )}
106
106
  {...props}
@@ -0,0 +1,74 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { GripVerticalIcon } from "lucide-react"
5
+ import {
6
+ Group,
7
+ Panel,
8
+ Separator,
9
+ type GroupProps,
10
+ type Orientation,
11
+ type PanelProps,
12
+ type SeparatorProps,
13
+ } from "react-resizable-panels"
14
+
15
+ import { cn } from "@/lib/utils"
16
+
17
+ type ResizablePanelGroupProps = Omit<GroupProps, "orientation"> & {
18
+ direction?: Orientation
19
+ }
20
+ type ResizablePanelProps = PanelProps
21
+ type ResizableHandleProps = SeparatorProps & {
22
+ withHandle?: boolean
23
+ }
24
+
25
+ function ResizablePanelGroup({
26
+ className,
27
+ direction = "horizontal",
28
+ ...props
29
+ }: ResizablePanelGroupProps) {
30
+ return (
31
+ <Group
32
+ data-panel-group-direction={direction}
33
+ data-slot="resizable-panel-group"
34
+ className={cn(
35
+ "flex h-full w-full data-[panel-group-direction=vertical]:flex-col",
36
+ className
37
+ )}
38
+ orientation={direction}
39
+ {...props}
40
+ />
41
+ )
42
+ }
43
+
44
+ const ResizablePanel = Panel
45
+
46
+ function ResizableHandle({
47
+ className,
48
+ withHandle = false,
49
+ ...props
50
+ }: ResizableHandleProps) {
51
+ return (
52
+ <Separator
53
+ data-slot="resizable-handle"
54
+ className={cn(
55
+ "relative flex w-[var(--bh-border-width-default)] items-center justify-center bg-[var(--bh-border-subtle)] outline-none transition-[background-color,box-shadow] after:absolute after:inset-y-0 after:start-1/2 after:w-[var(--bh-space-5xl-24)] after:-translate-x-1/2 focus-visible:shadow-[var(--shadow-button-focus)] aria-[orientation=horizontal]:h-[var(--bh-border-width-default)] aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:start-0 aria-[orientation=horizontal]:after:h-[var(--bh-space-5xl-24)] aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:-translate-y-1/2 aria-[orientation=horizontal]:after:translate-x-0",
56
+ className
57
+ )}
58
+ {...props}
59
+ >
60
+ {withHandle ? (
61
+ <div className="z-[var(--bh-z-raised)] flex h-[var(--bh-space-6xl-32)] w-[var(--bh-space-4xl-20)] items-center justify-center rounded-[var(--bh-radius-full)] border border-[var(--bh-border-subtle)] bg-[var(--bh-bg-raised)]">
62
+ <GripVerticalIcon className="size-[var(--bh-space-3xl-16)] text-[var(--bh-content-muted)]" />
63
+ </div>
64
+ ) : null}
65
+ </Separator>
66
+ )
67
+ }
68
+
69
+ export { ResizableHandle, ResizablePanel, ResizablePanelGroup }
70
+ export type {
71
+ ResizableHandleProps,
72
+ ResizablePanelGroupProps,
73
+ ResizablePanelProps,
74
+ }
@@ -0,0 +1,67 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ type ScrollAreaProps = React.ComponentPropsWithoutRef<
9
+ typeof ScrollAreaPrimitive.Root
10
+ >
11
+ type ScrollBarProps = React.ComponentPropsWithoutRef<
12
+ typeof ScrollAreaPrimitive.ScrollAreaScrollbar
13
+ >
14
+
15
+ const ScrollArea = React.forwardRef<
16
+ React.ElementRef<typeof ScrollAreaPrimitive.Root>,
17
+ ScrollAreaProps
18
+ >(function ScrollArea({ children, className, ...props }, ref) {
19
+ return (
20
+ <ScrollAreaPrimitive.Root
21
+ data-slot="scroll-area"
22
+ ref={ref}
23
+ className={cn("relative overflow-hidden", className)}
24
+ {...props}
25
+ >
26
+ <ScrollAreaPrimitive.Viewport
27
+ data-slot="scroll-area-viewport"
28
+ className="size-full rounded-[inherit]"
29
+ >
30
+ {children}
31
+ </ScrollAreaPrimitive.Viewport>
32
+ <ScrollBar />
33
+ <ScrollAreaPrimitive.Corner />
34
+ </ScrollAreaPrimitive.Root>
35
+ )
36
+ })
37
+
38
+ const ScrollBar = React.forwardRef<
39
+ React.ElementRef<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>,
40
+ ScrollBarProps
41
+ >(function ScrollBar({ className, orientation = "vertical", ...props }, ref) {
42
+ return (
43
+ <ScrollAreaPrimitive.ScrollAreaScrollbar
44
+ data-orientation={orientation}
45
+ data-slot="scroll-area-scrollbar"
46
+ orientation={orientation}
47
+ ref={ref}
48
+ className={cn(
49
+ "flex touch-none select-none bg-transparent p-[var(--bh-space-xxs-2)] transition-colors",
50
+ orientation === "vertical" &&
51
+ "h-full w-[var(--bh-space-lg-10)] border-s border-s-transparent",
52
+ orientation === "horizontal" &&
53
+ "h-[var(--bh-space-lg-10)] flex-col border-t border-t-transparent",
54
+ className
55
+ )}
56
+ {...props}
57
+ >
58
+ <ScrollAreaPrimitive.ScrollAreaThumb
59
+ data-slot="scroll-area-thumb"
60
+ className="relative flex-1 rounded-[var(--bh-radius-full)] bg-[var(--bh-border-default)]"
61
+ />
62
+ </ScrollAreaPrimitive.ScrollAreaScrollbar>
63
+ )
64
+ })
65
+
66
+ export { ScrollArea, ScrollBar }
67
+ export type { ScrollAreaProps, ScrollBarProps }
@@ -0,0 +1,87 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+
5
+ import {
6
+ ButtonGroupLabel,
7
+ ToggleGroup,
8
+ ToggleGroupItem,
9
+ type ButtonGroupLabelProps,
10
+ type ControlDensity,
11
+ type ToggleGroupItemProps,
12
+ type ToggleGroupProps,
13
+ } from "@/components/ui/button-group"
14
+
15
+ type SegmentedControlProps = Omit<
16
+ ToggleGroupProps,
17
+ "itemWidth" | "mode"
18
+ > & {
19
+ "aria-label": string
20
+ density?: ControlDensity
21
+ }
22
+
23
+ const SegmentedControl = React.forwardRef<
24
+ HTMLDivElement,
25
+ SegmentedControlProps
26
+ >(function SegmentedControl(
27
+ { density = "default", type = "single", ...props },
28
+ ref
29
+ ) {
30
+ return (
31
+ <ToggleGroup
32
+ data-slot="segmented-control"
33
+ density={density}
34
+ itemWidth="content"
35
+ mode="default"
36
+ ref={ref}
37
+ type={type}
38
+ {...props}
39
+ />
40
+ )
41
+ })
42
+
43
+ type SegmentedControlItemProps = ToggleGroupItemProps
44
+
45
+ const SegmentedControlItem = React.forwardRef<
46
+ HTMLButtonElement,
47
+ SegmentedControlItemProps
48
+ >(function SegmentedControlItem(props, ref) {
49
+ return (
50
+ <ToggleGroupItem
51
+ data-slot="segmented-control-item"
52
+ itemWidth="content"
53
+ ref={ref}
54
+ {...props}
55
+ />
56
+ )
57
+ })
58
+
59
+ type SegmentedControlLabelProps = Omit<
60
+ ButtonGroupLabelProps,
61
+ "itemWidth"
62
+ >
63
+
64
+ const SegmentedControlLabel = React.forwardRef<
65
+ HTMLSpanElement,
66
+ SegmentedControlLabelProps
67
+ >(function SegmentedControlLabel(props, ref) {
68
+ return (
69
+ <ButtonGroupLabel
70
+ data-slot="segmented-control-label"
71
+ itemWidth="content"
72
+ ref={ref}
73
+ {...props}
74
+ />
75
+ )
76
+ })
77
+
78
+ export {
79
+ SegmentedControl,
80
+ SegmentedControlItem,
81
+ SegmentedControlLabel,
82
+ }
83
+ export type {
84
+ SegmentedControlItemProps,
85
+ SegmentedControlLabelProps,
86
+ SegmentedControlProps,
87
+ }
@@ -104,7 +104,7 @@ function SelectItemCompanyLogo({
104
104
  aria-hidden="true"
105
105
  className="size-[var(--bh-select-company-icon-size)]"
106
106
  focusable="false"
107
- strokeWidth={2.2}
107
+ strokeWidth="var(--bh-icon-stroke-220)"
108
108
  />
109
109
  </span>
110
110
  )
@@ -177,7 +177,7 @@ function SelectIcon({
177
177
  "aria-hidden": true,
178
178
  className: iconClassName,
179
179
  focusable: false,
180
- strokeWidth: 2,
180
+ strokeWidth: "var(--bh-icon-stroke-200)",
181
181
  } as const
182
182
 
183
183
  if (name === "user") {