banhaten 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/CONTRIBUTING.md +44 -0
  3. package/README.md +65 -13
  4. package/SECURITY.md +15 -0
  5. package/banhaten.config.example.json +0 -2
  6. package/docs/design-system/README.md +9 -0
  7. package/docs/design-system/adoption-quality-remediation.md +87 -0
  8. package/docs/design-system/agent-usage.md +13 -0
  9. package/docs/design-system/appearance-presets.md +6 -1
  10. package/docs/design-system/component-docs-pattern.md +81 -0
  11. package/docs/design-system/component-implementation-ownership-audit.md +244 -0
  12. package/docs/design-system/component-quality-audit-2026-08-20.md +223 -0
  13. package/docs/design-system/component-showcase-consistency-report.md +2 -0
  14. package/docs/design-system/component-token-consistency-audit.md +13 -3
  15. package/docs/design-system/components/README.md +4 -2
  16. package/docs/design-system/components/accordion.md +16 -0
  17. package/docs/design-system/components/activity-feed.md +17 -1
  18. package/docs/design-system/components/activity-heatmap.md +73 -0
  19. package/docs/design-system/components/alert-dialog.md +17 -0
  20. package/docs/design-system/components/alert.md +46 -14
  21. package/docs/design-system/components/aspect-ratio.md +15 -0
  22. package/docs/design-system/components/attribute.md +16 -0
  23. package/docs/design-system/components/autocomplete.md +19 -0
  24. package/docs/design-system/components/avatar.md +18 -0
  25. package/docs/design-system/components/badge.md +19 -0
  26. package/docs/design-system/components/banner.md +19 -1
  27. package/docs/design-system/components/breadcrumbs.md +17 -0
  28. package/docs/design-system/components/button-group.md +35 -0
  29. package/docs/design-system/components/button.md +18 -0
  30. package/docs/design-system/components/card.md +26 -1
  31. package/docs/design-system/components/carousel.md +20 -3
  32. package/docs/design-system/components/catalog-components.md +18 -1
  33. package/docs/design-system/components/chart.md +15 -0
  34. package/docs/design-system/components/checkbox.md +16 -0
  35. package/docs/design-system/components/collapsible.md +15 -0
  36. package/docs/design-system/components/command.md +15 -0
  37. package/docs/design-system/components/context-menu.md +15 -0
  38. package/docs/design-system/components/date-picker.md +21 -1
  39. package/docs/design-system/components/divider.md +16 -0
  40. package/docs/design-system/components/empty-state.md +17 -0
  41. package/docs/design-system/components/field.md +17 -0
  42. package/docs/design-system/components/file-upload.md +18 -0
  43. package/docs/design-system/components/hover-card.md +15 -0
  44. package/docs/design-system/components/input-group.md +17 -0
  45. package/docs/design-system/components/input-otp.md +18 -0
  46. package/docs/design-system/components/input.md +43 -7
  47. package/docs/design-system/components/item.md +72 -0
  48. package/docs/design-system/components/kbd.md +18 -0
  49. package/docs/design-system/components/label.md +16 -0
  50. package/docs/design-system/components/menu.md +17 -0
  51. package/docs/design-system/components/menubar.md +15 -0
  52. package/docs/design-system/components/modal.md +25 -4
  53. package/docs/design-system/components/native-select.md +18 -0
  54. package/docs/design-system/components/navigation-menu.md +15 -0
  55. package/docs/design-system/components/onboarding-step-list-item.md +16 -1
  56. package/docs/design-system/components/page-header.md +17 -1
  57. package/docs/design-system/components/pagination.md +31 -8
  58. package/docs/design-system/components/popover.md +19 -0
  59. package/docs/design-system/components/progress-slider.md +18 -0
  60. package/docs/design-system/components/progress.md +17 -0
  61. package/docs/design-system/components/radio-card.md +16 -0
  62. package/docs/design-system/components/radio-group.md +17 -0
  63. package/docs/design-system/components/resizable.md +15 -0
  64. package/docs/design-system/components/scroll-area.md +20 -1
  65. package/docs/design-system/components/segmented-control.md +71 -0
  66. package/docs/design-system/components/select.md +44 -7
  67. package/docs/design-system/components/sheet.md +17 -0
  68. package/docs/design-system/components/sidebar.md +17 -0
  69. package/docs/design-system/components/skeleton.md +18 -0
  70. package/docs/design-system/components/slideout.md +17 -0
  71. package/docs/design-system/components/slider.md +20 -0
  72. package/docs/design-system/components/social-button.md +21 -3
  73. package/docs/design-system/components/spinner.md +16 -0
  74. package/docs/design-system/components/steps.md +19 -0
  75. package/docs/design-system/components/table.md +36 -4
  76. package/docs/design-system/components/tabs.md +17 -0
  77. package/docs/design-system/components/tag.md +17 -0
  78. package/docs/design-system/components/textarea.md +16 -0
  79. package/docs/design-system/components/timeline.md +17 -0
  80. package/docs/design-system/components/toast.md +17 -0
  81. package/docs/design-system/components/toggle.md +17 -0
  82. package/docs/design-system/components/toolbar.md +21 -1
  83. package/docs/design-system/components/tooltip.md +18 -1
  84. package/docs/design-system/density-and-elevation.md +61 -0
  85. package/docs/design-system/direction-and-localization.md +23 -0
  86. package/docs/design-system/form-recipes.md +73 -0
  87. package/docs/design-system/gap-promotion-policy.md +21 -0
  88. package/docs/design-system/gap-promotion-report.md +100 -0
  89. package/docs/design-system/installation.md +68 -0
  90. package/docs/design-system/launch-comparison-shadcn.md +98 -0
  91. package/docs/design-system/registry-and-cli.md +30 -7
  92. package/docs/design-system/release-policy.md +30 -0
  93. package/docs/design-system/roadmap.md +14 -0
  94. package/docs/design-system/support-matrix.md +23 -0
  95. package/docs/design-system/tabs.md +1 -1
  96. package/docs/design-system/token-governance.md +23 -1
  97. package/package.json +30 -15
  98. package/registry/component-contract.json +40 -0
  99. package/registry/components/alert-dialog.tsx +2 -2
  100. package/registry/components/alert.tsx +101 -76
  101. package/registry/components/autocomplete.tsx +23 -9
  102. package/registry/components/avatar.tsx +14 -10
  103. package/registry/components/badge.tsx +18 -18
  104. package/registry/components/button-group.tsx +324 -5
  105. package/registry/components/button.tsx +38 -17
  106. package/registry/components/card.tsx +87 -62
  107. package/registry/components/carousel.tsx +67 -5
  108. package/registry/components/chart.tsx +36 -3
  109. package/registry/components/checkbox.tsx +3 -3
  110. package/registry/components/collapsible.tsx +1 -1
  111. package/registry/components/command.tsx +38 -4
  112. package/registry/components/context-menu.tsx +1 -1
  113. package/registry/components/date-picker.tsx +312 -135
  114. package/registry/components/expanded/ActivityFeed.tsx +9 -22
  115. package/registry/components/expanded/ActivityHeatmap.tsx +64 -0
  116. package/registry/components/expanded/Banner.tsx +3 -4
  117. package/registry/components/expanded/Breadcrumbs.tsx +8 -5
  118. package/registry/components/expanded/CatalogComponentsShowcase.tsx +16 -17
  119. package/registry/components/expanded/CatalogDivider.tsx +4 -3
  120. package/registry/components/expanded/EmptyState.tsx +1 -1
  121. package/registry/components/expanded/FileUpload.tsx +16 -7
  122. package/registry/components/expanded/OnboardingStepListItem.tsx +2 -6
  123. package/registry/components/expanded/PageHeader.tsx +47 -56
  124. package/registry/components/expanded/Slideout.tsx +29 -424
  125. package/registry/components/expanded/Steps.tsx +151 -13
  126. package/registry/components/expanded/Table.tsx +161 -82
  127. package/registry/components/expanded/Timeline.tsx +14 -27
  128. package/registry/components/expanded/activityFeed.css +9 -9
  129. package/registry/components/expanded/activityHeatmap.css +66 -0
  130. package/registry/components/expanded/banner.css +21 -11
  131. package/registry/components/expanded/breadcrumbs.css +2 -2
  132. package/registry/components/expanded/divider.css +1 -1
  133. package/registry/components/expanded/emptyState.css +1 -1
  134. package/registry/components/expanded/fileUpload.css +7 -7
  135. package/registry/components/expanded/onboardingStepListItem.css +2 -2
  136. package/registry/components/expanded/pageHeader.css +14 -11
  137. package/registry/components/expanded/slideout.css +10 -690
  138. package/registry/components/expanded/steps.css +78 -15
  139. package/registry/components/expanded/table.css +60 -69
  140. package/registry/components/expanded/timeline.css +19 -18
  141. package/registry/components/field.tsx +61 -8
  142. package/registry/components/input-content.ts +1 -0
  143. package/registry/components/input-otp.tsx +13 -3
  144. package/registry/components/input.tsx +68 -43
  145. package/registry/components/item.tsx +189 -0
  146. package/registry/components/kbd.tsx +111 -4
  147. package/registry/components/menu.tsx +87 -251
  148. package/registry/components/menubar.tsx +1 -1
  149. package/registry/components/modal.tsx +143 -103
  150. package/registry/components/native-select.tsx +2 -2
  151. package/registry/components/navigation-menu.tsx +1 -1
  152. package/registry/components/pagination.css +36 -0
  153. package/registry/components/pagination.tsx +88 -64
  154. package/registry/components/popover.tsx +162 -664
  155. package/registry/components/progress-slider.tsx +1 -1
  156. package/registry/components/radio-card.tsx +116 -87
  157. package/registry/components/resizable.tsx +36 -2
  158. package/registry/components/scroll-area.tsx +30 -6
  159. package/registry/components/segmented-control.tsx +87 -0
  160. package/registry/components/select-content.tsx +2 -2
  161. package/registry/components/select.tsx +86 -27
  162. package/registry/components/sheet.tsx +1 -1
  163. package/registry/components/sidebar.tsx +12 -6
  164. package/registry/components/skeleton.css +0 -3
  165. package/registry/components/social-button.tsx +59 -30
  166. package/registry/components/spinner.tsx +18 -55
  167. package/registry/components/table-elements.tsx +128 -0
  168. package/registry/components/tabs.css +1 -1
  169. package/registry/components/tabs.tsx +13 -14
  170. package/registry/components/tag.tsx +3 -3
  171. package/registry/components/textarea.tsx +3 -3
  172. package/registry/components/toast.tsx +16 -11
  173. package/registry/components/toggle.tsx +4 -4
  174. package/registry/components/toolbar.tsx +94 -22
  175. package/registry/components/tooltip.tsx +2 -2
  176. package/registry/examples/alert-demo.tsx +25 -5
  177. package/registry/examples/attribute-demo.tsx +1 -1
  178. package/registry/examples/autocomplete-demo.tsx +3 -3
  179. package/registry/examples/avatar-demo.tsx +14 -11
  180. package/registry/examples/badge-demo.tsx +1 -1
  181. package/registry/examples/button-demo.tsx +6 -6
  182. package/registry/examples/button-group-demo.tsx +23 -2
  183. package/registry/examples/card-demo.tsx +46 -8
  184. package/registry/examples/carousel-demo.tsx +20 -2
  185. package/registry/examples/chart-demo.tsx +1 -1
  186. package/registry/examples/checkbox-demo.tsx +5 -5
  187. package/registry/examples/collection-filter-bar-demo.tsx +135 -0
  188. package/registry/examples/command-demo.tsx +3 -3
  189. package/registry/examples/{expanded/command-bar-demo.tsx → command-palette-demo.tsx} +5 -15
  190. package/registry/examples/context-menu-demo.tsx +1 -1
  191. package/registry/examples/control-density-contract-demo.tsx +61 -0
  192. package/registry/examples/date-picker-demo.tsx +12 -12
  193. package/registry/examples/divider-demo.tsx +3 -3
  194. package/registry/examples/expanded/activity-heatmap-demo.tsx +29 -0
  195. package/registry/examples/expanded/banner-demo.tsx +1 -1
  196. package/registry/examples/expanded/breadcrumbs-demo.tsx +4 -4
  197. package/registry/examples/expanded/empty-state-demo.tsx +1 -1
  198. package/registry/examples/expanded/file-upload-demo.tsx +1 -1
  199. package/registry/examples/expanded/onboarding-step-demo.tsx +1 -1
  200. package/registry/examples/expanded/slideout-demo.tsx +2 -2
  201. package/registry/examples/expanded/steps-demo.tsx +1 -1
  202. package/registry/examples/expanded/tabs-demo.tsx +1 -1
  203. package/registry/examples/expanded/timeline-demo.tsx +1 -1
  204. package/registry/examples/hover-card-demo.tsx +2 -2
  205. package/registry/examples/input-demo.tsx +6 -6
  206. package/registry/examples/input-otp-demo.tsx +4 -4
  207. package/registry/examples/item-demo.tsx +46 -0
  208. package/registry/examples/kbd-demo.tsx +1 -1
  209. package/registry/examples/label-demo.tsx +1 -1
  210. package/registry/examples/menu-demo.tsx +1 -1
  211. package/registry/examples/modal-demo.tsx +67 -9
  212. package/registry/examples/navigation-menu-demo.tsx +1 -1
  213. package/registry/examples/pagination-demo.tsx +10 -7
  214. package/registry/examples/popover-demo.tsx +19 -19
  215. package/registry/examples/progress-demo.tsx +1 -1
  216. package/registry/examples/progress-slider-demo.tsx +1 -1
  217. package/registry/examples/radio-card-demo.tsx +4 -4
  218. package/registry/examples/radio-group-demo.tsx +2 -2
  219. package/registry/examples/resizable-demo.tsx +1 -1
  220. package/registry/examples/results-toolbar-demo.tsx +44 -0
  221. package/registry/examples/scroll-area-demo.tsx +3 -3
  222. package/registry/examples/segmented-control-demo.tsx +39 -0
  223. package/registry/examples/select-demo.tsx +1 -1
  224. package/registry/examples/sidebar-demo.tsx +5 -3
  225. package/registry/examples/slider-demo.tsx +3 -3
  226. package/registry/examples/social-button-demo.tsx +18 -8
  227. package/registry/examples/spinner-demo.tsx +13 -13
  228. package/registry/examples/tabs-demo.tsx +1 -1
  229. package/registry/examples/tag-demo.tsx +1 -1
  230. package/registry/examples/textarea-demo.tsx +4 -4
  231. package/registry/examples/toast-demo.tsx +1 -1
  232. package/registry/examples/toggle-demo.tsx +6 -6
  233. package/registry/examples/tooltip-demo.tsx +4 -4
  234. package/registry/guidance/USAGE.md +27 -0
  235. package/registry/hooks/use-direction.ts +193 -13
  236. package/registry/index.json +5668 -375
  237. package/registry/styles/globals.css +2404 -3999
  238. package/registry.json +156 -149
  239. package/schema/config.schema.json +11 -8
  240. package/schema/registry.schema.json +150 -45
  241. package/schema/tokens.schema.json +134 -34
  242. package/src/cli/command-line.js +194 -0
  243. package/src/cli/config-editors.js +9 -0
  244. package/src/cli/doctor.js +399 -0
  245. package/src/cli/file-transaction.js +295 -0
  246. package/src/cli/global-css.js +153 -0
  247. package/src/cli/index.js +567 -1613
  248. package/src/cli/install-plan.js +592 -0
  249. package/src/cli/install-receipt.js +171 -0
  250. package/src/cli/jsonc.js +203 -0
  251. package/src/cli/package-install-state.js +254 -0
  252. package/src/cli/package-manager.js +238 -0
  253. package/src/cli/package-plan.js +185 -0
  254. package/src/cli/package-version.js +97 -0
  255. package/src/cli/registry-query.js +207 -0
  256. package/src/cli/reporting.js +55 -0
  257. package/src/cli/schema-validation.js +19 -0
  258. package/src/cli/source-scanner.js +686 -0
  259. package/src/cli/vite-config.js +478 -0
  260. package/tokens/banhaten.tokens.json +4444 -331
  261. package/docs/design-system/components/command-bar.md +0 -57
  262. package/registry/components/expanded/BannerBoard.tsx +0 -225
  263. package/registry/components/expanded/CatalogTag.tsx +0 -85
  264. package/registry/components/expanded/CommandBar.tsx +0 -386
  265. package/registry/components/expanded/IconExplorer.tsx +0 -612
  266. package/registry/components/expanded/TimelineShowcase.tsx +0 -158
  267. package/registry/components/expanded/commandBar.css +0 -470
  268. package/registry/components/expanded/iconExplorer.css +0 -764
  269. package/registry/components/expanded/iconPacks.ts +0 -866
  270. package/registry/components/expanded/tag.css +0 -148
  271. package/registry/examples/expanded/icons-demo.tsx +0 -5
  272. package/tokens/Color mode.zip +0 -0
  273. package/tokens/Numbers.zip +0 -0
  274. package/tokens/Radius.zip +0 -0
  275. package/tokens/Theme.zip +0 -0
@@ -1,4 +1,5 @@
1
1
  import {
2
+ arabicCarouselMessages,
2
3
  Carousel,
3
4
  CarouselContent,
4
5
  CarouselItem,
@@ -8,7 +9,24 @@ import {
8
9
 
9
10
  export function CarouselDemo() {
10
11
  return (
11
- <Carousel className="w-full max-w-sm">
12
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
13
+ <Carousel className="w-full max-w-sm">
14
+ <CarouselSlides />
15
+ </Carousel>
16
+ <Carousel
17
+ className="w-full max-w-sm"
18
+ dir="rtl"
19
+ messages={arabicCarouselMessages}
20
+ >
21
+ <CarouselSlides />
22
+ </Carousel>
23
+ </div>
24
+ )
25
+ }
26
+
27
+ function CarouselSlides() {
28
+ return (
29
+ <>
12
30
  <CarouselContent>
13
31
  {[1, 2, 3].map((item) => (
14
32
  <CarouselItem key={item}>
@@ -20,6 +38,6 @@ export function CarouselDemo() {
20
38
  </CarouselContent>
21
39
  <CarouselPrevious />
22
40
  <CarouselNext />
23
- </Carousel>
41
+ </>
24
42
  )
25
43
  }
@@ -24,7 +24,7 @@ export function ChartDemo() {
24
24
  dataKey="revenue"
25
25
  type="monotone"
26
26
  stroke="var(--color-revenue)"
27
- strokeWidth={2}
27
+ strokeWidth="var(--bh-icon-stroke-200)"
28
28
  dot={false}
29
29
  />
30
30
  </LineChart>
@@ -8,8 +8,8 @@ export function CheckboxDemo() {
8
8
  const [checked, setChecked] = React.useState(true)
9
9
 
10
10
  return (
11
- <div className="grid gap-6">
12
- <div className="flex flex-wrap items-center gap-4">
11
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
12
+ <div className="flex flex-wrap items-center gap-[var(--bh-space-3xl-16)]">
13
13
  <Checkbox
14
14
  checked={checked}
15
15
  onCheckedChange={(value) => setChecked(value === true)}
@@ -20,7 +20,7 @@ export function CheckboxDemo() {
20
20
  <Checkbox disabled aria-label="Disabled option" />
21
21
  </div>
22
22
 
23
- <div className="grid gap-3">
23
+ <div className="grid gap-[var(--bh-space-xl-12)]">
24
24
  <CheckboxCard
25
25
  checked
26
26
  label="Label"
@@ -40,7 +40,7 @@ export function CheckboxDemo() {
40
40
  />
41
41
  </div>
42
42
 
43
- <div dir="rtl" className="grid gap-3">
43
+ <div dir="rtl" className="grid gap-[var(--bh-space-xl-12)]">
44
44
  <CheckboxCard
45
45
  checked
46
46
  label={"\u0627\u0644\u062a\u0633\u0645\u064a\u0629"}
@@ -58,5 +58,5 @@ export function CheckboxDemo() {
58
58
  }
59
59
 
60
60
  function UserLineIcon() {
61
- return <UserIcon aria-hidden="true" focusable="false" strokeWidth={2.1} />
61
+ return <UserIcon aria-hidden="true" focusable="false" strokeWidth="var(--bh-icon-stroke-210)" />
62
62
  }
@@ -0,0 +1,135 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+
5
+ import { DatePicker } from "@/components/ui/date-picker"
6
+ import { Field, FieldLabel } from "@/components/ui/field"
7
+ import {
8
+ Select,
9
+ SelectMenuItem,
10
+ } from "@/components/ui/select"
11
+ import {
12
+ ToolbarButton,
13
+ ToolbarSearch,
14
+ } from "@/components/ui/toolbar"
15
+
16
+ const typeLabels = {
17
+ everything: "Everything",
18
+ articles: "Articles",
19
+ videos: "Videos",
20
+ }
21
+
22
+ const orderLabels = {
23
+ recent: "Recently bookmarked",
24
+ oldest: "Oldest bookmarked",
25
+ title: "Title",
26
+ }
27
+
28
+ export function CollectionFilterBarDemo() {
29
+ const [typeFilter, setTypeFilter] = React.useState<keyof typeof typeLabels>(
30
+ "everything"
31
+ )
32
+ const [order, setOrder] = React.useState<keyof typeof orderLabels>("recent")
33
+ const [dateRevision, setDateRevision] = React.useState(0)
34
+
35
+ return (
36
+ <form
37
+ aria-label="Collection filters"
38
+ data-recipe="collection-filter-bar"
39
+ className="grid w-full min-w-0 gap-[var(--bh-space-xl-12)] rounded-[var(--bh-radius-2xl-12)] bg-[var(--bh-bg-raised)] p-[var(--bh-space-3xl-16)] shadow-[var(--shadow-component-default)]"
40
+ onReset={() => {
41
+ setTypeFilter("everything")
42
+ setOrder("recent")
43
+ setDateRevision((revision) => revision + 1)
44
+ }}
45
+ >
46
+ <ToolbarSearch
47
+ aria-label="Search bookmarks"
48
+ density="default"
49
+ placeholder="Search words, people, or folders"
50
+ shortcutKeys={["Mod", "F"]}
51
+ width="full"
52
+ />
53
+
54
+ <div className="flex min-w-0 flex-wrap items-end gap-[var(--bh-space-xl-12)]">
55
+ <Field
56
+ className="flex-[1_1_var(--bh-date-trigger-width)]"
57
+ controlId="collection-filter-from"
58
+ >
59
+ <FieldLabel tone="subtle">From</FieldLabel>
60
+ <DatePicker
61
+ key={`from-${dateRevision}`}
62
+ className="w-full"
63
+ density="default"
64
+ placeholder="dd/mm/yyyy"
65
+ triggerClassName="w-full"
66
+ triggerProps={{ id: "collection-filter-from" }}
67
+ />
68
+ </Field>
69
+
70
+ <Field
71
+ className="flex-[1_1_var(--bh-date-trigger-width)]"
72
+ controlId="collection-filter-to"
73
+ >
74
+ <FieldLabel tone="subtle">To</FieldLabel>
75
+ <DatePicker
76
+ key={`to-${dateRevision}`}
77
+ className="w-full"
78
+ density="default"
79
+ placeholder="dd/mm/yyyy"
80
+ triggerClassName="w-full"
81
+ triggerProps={{ id: "collection-filter-to" }}
82
+ />
83
+ </Field>
84
+
85
+ <Field
86
+ className="flex-[1_1_var(--bh-date-trigger-width)]"
87
+ controlId="collection-filter-type"
88
+ >
89
+ <FieldLabel tone="subtle">Type</FieldLabel>
90
+ <Select
91
+ className="w-full"
92
+ density="default"
93
+ onValueChange={(value) =>
94
+ setTypeFilter(value as keyof typeof typeLabels)
95
+ }
96
+ selectValue={typeFilter}
97
+ triggerId="collection-filter-type"
98
+ value={typeLabels[typeFilter]}
99
+ >
100
+ <SelectMenuItem label="Everything" value="everything" />
101
+ <SelectMenuItem label="Articles" value="articles" />
102
+ <SelectMenuItem label="Videos" value="videos" />
103
+ </Select>
104
+ </Field>
105
+
106
+ <Field
107
+ className="flex-[1_1_var(--bh-date-trigger-width)]"
108
+ controlId="collection-filter-order"
109
+ >
110
+ <FieldLabel tone="subtle">Order</FieldLabel>
111
+ <Select
112
+ className="w-full"
113
+ density="default"
114
+ onValueChange={(value) =>
115
+ setOrder(value as keyof typeof orderLabels)
116
+ }
117
+ selectValue={order}
118
+ triggerId="collection-filter-order"
119
+ value={orderLabels[order]}
120
+ >
121
+ <SelectMenuItem label="Recently bookmarked" value="recent" />
122
+ <SelectMenuItem label="Oldest bookmarked" value="oldest" />
123
+ <SelectMenuItem label="Title" value="title" />
124
+ </Select>
125
+ </Field>
126
+
127
+ <div className="flex items-end">
128
+ <ToolbarButton density="default" type="reset" variant="link">
129
+ Reset
130
+ </ToolbarButton>
131
+ </div>
132
+ </div>
133
+ </form>
134
+ )
135
+ }
@@ -19,12 +19,12 @@ export function CommandDemo() {
19
19
  <CommandEmpty>No results found.</CommandEmpty>
20
20
  <CommandGroup heading="Pages">
21
21
  <CommandItem value="profile">
22
- <UserIcon className="size-4" />
22
+ <UserIcon className="size-[var(--bh-space-3xl-16)]" />
23
23
  Profile
24
24
  <CommandShortcut>⌘P</CommandShortcut>
25
25
  </CommandItem>
26
26
  <CommandItem value="docs">
27
- <FileTextIcon className="size-4" />
27
+ <FileTextIcon className="size-[var(--bh-space-3xl-16)]" />
28
28
  Docs
29
29
  <CommandShortcut>⌘D</CommandShortcut>
30
30
  </CommandItem>
@@ -32,7 +32,7 @@ export function CommandDemo() {
32
32
  <CommandSeparator />
33
33
  <CommandGroup heading="Actions">
34
34
  <CommandItem value="settings">
35
- <SettingsIcon className="size-4" />
35
+ <SettingsIcon className="size-[var(--bh-space-3xl-16)]" />
36
36
  Settings
37
37
  </CommandItem>
38
38
  </CommandGroup>
@@ -21,7 +21,7 @@ import { Avatar, AvatarIcon, AvatarStatus } from "@/components/ui/avatar"
21
21
  import { Badge } from "@/components/ui/badge"
22
22
  import { Button } from "@/components/ui/button"
23
23
  import {
24
- Menu,
24
+ MenuPreview,
25
25
  MenuItem,
26
26
  MenuItemDescription,
27
27
  MenuItemText,
@@ -34,7 +34,6 @@ import {
34
34
  ToolbarSearch,
35
35
  ToolbarSection,
36
36
  } from "@/components/ui/toolbar"
37
- import { CommandBar } from "@/components/ui/expanded/CommandBar"
38
37
 
39
38
  type ToolTone = "neutral" | "blue" | "green" | "amber" | "purple" | "sky"
40
39
  type ToolIcon = React.ComponentType<React.SVGProps<SVGSVGElement>>
@@ -96,16 +95,7 @@ const toolToneClassNames: Record<ToolTone, string> = {
96
95
  sky: "text-[var(--bh-content-accent-sky-default)]",
97
96
  }
98
97
 
99
- export function CommandBarDemo() {
100
- return (
101
- <div className="grid gap-6">
102
- <CommandBar />
103
- <CommandBar type="results" />
104
- </div>
105
- )
106
- }
107
-
108
- export function AddToolPickerExample() {
98
+ export function CommandPaletteDemo() {
109
99
  return (
110
100
  <ModalSurface
111
101
  aria-label="Add tool command example"
@@ -197,7 +187,7 @@ function ToolRow({ item }: { item: ToolItem }) {
197
187
  const tone = item.tone ?? "neutral"
198
188
 
199
189
  return (
200
- <Menu
190
+ <MenuPreview
201
191
  aria-label={`${item.title} tool action`}
202
192
  className="w-full bg-transparent p-0 shadow-none"
203
193
  width="auto"
@@ -217,7 +207,7 @@ function ToolRow({ item }: { item: ToolItem }) {
217
207
  ].join(" ")}
218
208
  size="lg"
219
209
  >
220
- <Icon aria-hidden="true" strokeWidth={2} />
210
+ <Icon aria-hidden="true" strokeWidth="var(--bh-icon-stroke-200)" />
221
211
  </AvatarIcon>
222
212
  {item.added ? <AvatarStatus size="small" status="available" /> : null}
223
213
  </Avatar>
@@ -241,6 +231,6 @@ function ToolRow({ item }: { item: ToolItem }) {
241
231
  ) : null}
242
232
  </MenuItemText>
243
233
  </MenuItem>
244
- </Menu>
234
+ </MenuPreview>
245
235
  )
246
236
  }
@@ -11,7 +11,7 @@ import {
11
11
  export function ContextMenuDemo() {
12
12
  return (
13
13
  <ContextMenu>
14
- <ContextMenuTrigger className="flex h-32 w-64 items-center justify-center rounded-xl border border-dashed border-[var(--bh-border-default)] text-sm">
14
+ <ContextMenuTrigger className="flex h-[var(--bh-space-12xl-128)] w-[var(--bh-space-16xl-256)] items-center justify-center rounded-xl border border-dashed border-[var(--bh-border-default)] text-sm">
15
15
  Right click
16
16
  </ContextMenuTrigger>
17
17
  <ContextMenuContent>
@@ -0,0 +1,61 @@
1
+ import { Button } from "@/components/ui/button"
2
+ import { DatePicker } from "@/components/ui/date-picker"
3
+ import { Input } from "@/components/ui/input"
4
+ import {
5
+ SegmentedControl,
6
+ SegmentedControlItem,
7
+ } from "@/components/ui/segmented-control"
8
+ import { Select } from "@/components/ui/select"
9
+ import { ToolbarSearch } from "@/components/ui/toolbar"
10
+
11
+ const densities = ["compact", "default", "comfortable"] as const
12
+
13
+ export function ControlDensityContractDemo() {
14
+ return (
15
+ <div
16
+ id="control-density-contract"
17
+ className="grid w-full min-w-0 gap-[var(--bh-space-3xl-16)]"
18
+ >
19
+ {densities.map((density) => (
20
+ <section
21
+ key={density}
22
+ data-control-density-row={density}
23
+ className="grid min-w-0 gap-[var(--bh-space-md-8)] rounded-[var(--bh-radius-xl-10)] bg-[var(--bh-bg-default)] p-[var(--bh-space-xl-12)]"
24
+ >
25
+ <p className="font-mono text-[length:var(--bh-text-body-xs-medium-font-size)] font-[var(--bh-text-body-xs-medium-font-weight)] uppercase text-[var(--bh-content-subtle)]">
26
+ {density}
27
+ </p>
28
+ <div className="flex min-w-0 flex-wrap items-center gap-[var(--bh-space-xl-12)]">
29
+ <Input
30
+ density={density}
31
+ hasHelperText={false}
32
+ hasLabel={false}
33
+ placeholder="Input"
34
+ />
35
+ <Select density={density} value="Select" />
36
+ <DatePicker
37
+ density={density}
38
+ placeholder="Date"
39
+ triggerProps={{ "aria-label": `${density} date` }}
40
+ />
41
+ <Button density={density}>Button</Button>
42
+ <SegmentedControl
43
+ aria-label={`${density} view`}
44
+ defaultValue="grid"
45
+ density={density}
46
+ >
47
+ <SegmentedControlItem value="grid">Grid</SegmentedControlItem>
48
+ <SegmentedControlItem value="list">List</SegmentedControlItem>
49
+ </SegmentedControl>
50
+ <ToolbarSearch
51
+ aria-label={`${density} search`}
52
+ density={density}
53
+ placeholder="Search"
54
+ width="compact"
55
+ />
56
+ </div>
57
+ </section>
58
+ ))}
59
+ </div>
60
+ )
61
+ }
@@ -13,15 +13,15 @@ const selectedRange: CalendarRange = {
13
13
  }
14
14
 
15
15
  const staticPopoverClassName =
16
- "static left-auto top-auto mt-2 translate-x-0"
16
+ "static left-auto top-auto mt-[var(--bh-space-md-8)] translate-x-0"
17
17
  const datePickerClassName =
18
18
  "w-[var(--bh-date-surface-width-picker)] max-w-full"
19
19
  const dateRangePickerClassName = "w-max max-w-none"
20
20
 
21
21
  export function DatePickerDemo() {
22
22
  return (
23
- <div className="grid gap-8">
24
- <div className="grid gap-6 lg:grid-cols-[repeat(auto-fit,minmax(260px,max-content))]">
23
+ <div className="grid gap-[var(--bh-space-6xl-32)]">
24
+ <div className="grid gap-[var(--bh-space-5xl-24)] lg:grid-cols-[repeat(auto-fit,minmax(calc(var(--bh-space-16xl-256)_+_var(--bh-space-xs-4)),max-content))]">
25
25
  <div data-date-demo-item>
26
26
  <Calendar value={selectedDate} />
27
27
  </div>
@@ -30,7 +30,7 @@ export function DatePickerDemo() {
30
30
  </div>
31
31
  </div>
32
32
 
33
- <div className="grid gap-6 xl:grid-cols-2">
33
+ <div className="grid gap-[var(--bh-space-5xl-24)] xl:grid-cols-2">
34
34
  <div data-date-demo-item>
35
35
  <DatePicker
36
36
  calendarProps={{ className: staticPopoverClassName }}
@@ -48,7 +48,7 @@ export function DatePickerDemo() {
48
48
  </div>
49
49
  </div>
50
50
 
51
- <div className="grid gap-6 xl:grid-cols-2">
51
+ <div className="grid gap-[var(--bh-space-5xl-24)] xl:grid-cols-2">
52
52
  <div data-date-demo-item>
53
53
  <DatePicker
54
54
  calendarProps={{ className: staticPopoverClassName }}
@@ -69,7 +69,7 @@ export function DatePickerDemo() {
69
69
  </div>
70
70
  </div>
71
71
 
72
- <div className="grid gap-6 overflow-x-auto">
72
+ <div className="grid gap-[var(--bh-space-5xl-24)] overflow-x-auto">
73
73
  <div data-date-demo-item>
74
74
  <RangeCalendar value={selectedRange} />
75
75
  </div>
@@ -81,15 +81,15 @@ export function DatePickerDemo() {
81
81
  </div>
82
82
  </div>
83
83
 
84
- <div className="grid gap-6 xl:grid-cols-2">
85
- <div data-date-demo-item className="overflow-x-auto pb-2">
84
+ <div className="grid gap-[var(--bh-space-5xl-24)] xl:grid-cols-2">
85
+ <div data-date-demo-item className="overflow-x-auto pb-[var(--bh-space-md-8)]">
86
86
  <DateRangePicker
87
87
  calendarProps={{ className: staticPopoverClassName }}
88
88
  className={dateRangePickerClassName}
89
89
  value={selectedRange}
90
90
  />
91
91
  </div>
92
- <div data-date-demo-item className="overflow-x-auto pb-2" dir="rtl">
92
+ <div data-date-demo-item className="overflow-x-auto pb-[var(--bh-space-md-8)]" dir="rtl">
93
93
  <DateRangePicker
94
94
  calendarProps={{ className: staticPopoverClassName }}
95
95
  className={dateRangePickerClassName}
@@ -100,8 +100,8 @@ export function DatePickerDemo() {
100
100
  </div>
101
101
  </div>
102
102
 
103
- <div className="grid gap-6">
104
- <div data-date-demo-item className="overflow-x-auto pb-2">
103
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
104
+ <div data-date-demo-item className="overflow-x-auto pb-[var(--bh-space-md-8)]">
105
105
  <DateRangePicker
106
106
  calendarProps={{ className: staticPopoverClassName }}
107
107
  className={dateRangePickerClassName}
@@ -110,7 +110,7 @@ export function DatePickerDemo() {
110
110
  value={selectedRange}
111
111
  />
112
112
  </div>
113
- <div data-date-demo-item className="overflow-x-auto pb-2" dir="rtl">
113
+ <div data-date-demo-item className="overflow-x-auto pb-[var(--bh-space-md-8)]" dir="rtl">
114
114
  <DateRangePicker
115
115
  calendarProps={{ className: staticPopoverClassName }}
116
116
  className={dateRangePickerClassName}
@@ -2,13 +2,13 @@ import { Divider } from "@/components/ui/divider"
2
2
 
3
3
  export function DividerDemo() {
4
4
  return (
5
- <div className="grid gap-6">
6
- <div className="grid gap-4">
5
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
6
+ <div className="grid gap-[var(--bh-space-3xl-16)]">
7
7
  <Divider />
8
8
  <Divider type="dotted" />
9
9
  </div>
10
10
 
11
- <div className="flex h-[var(--bh-space-15xl-224)] items-start gap-6">
11
+ <div className="flex h-[var(--bh-space-15xl-224)] items-start gap-[var(--bh-space-5xl-24)]">
12
12
  <Divider direction="vertical" type="dotted" />
13
13
  <Divider direction="vertical" />
14
14
  </div>
@@ -0,0 +1,29 @@
1
+ import {
2
+ ActivityHeatmap,
3
+ type ActivityHeatmapItem,
4
+ type ActivityHeatmapLevel,
5
+ } from "@/components/ui/expanded/ActivityHeatmap"
6
+
7
+ const activityItems: ActivityHeatmapItem[] = Array.from(
8
+ { length: 39 * 7 },
9
+ (_, index) => {
10
+ const column = Math.floor(index / 7)
11
+ const row = index % 7
12
+ const level = ((column * 11 + row * 7 + column * row * 3) % 5) as ActivityHeatmapLevel
13
+
14
+ return {
15
+ id: `activity-${index}`,
16
+ label: `Activity level ${level} of 4`,
17
+ level,
18
+ }
19
+ }
20
+ )
21
+
22
+ export function ActivityHeatmapDemo() {
23
+ return (
24
+ <ActivityHeatmap
25
+ ariaLabel="Weekly activity over the last 39 weeks"
26
+ items={activityItems}
27
+ />
28
+ )
29
+ }
@@ -20,7 +20,7 @@ const rtlBannerDemoCopy = {
20
20
 
21
21
  export function BannerDemo() {
22
22
  return (
23
- <div className="grid gap-4">
23
+ <div className="grid gap-[var(--bh-space-3xl-16)]">
24
24
  <Banner {...bannerDemoCopy} />
25
25
  <Banner {...bannerDemoCopy} type="single-action-inline" />
26
26
  <Banner {...bannerDemoCopy} size="full-width" type="single-action" />
@@ -29,17 +29,17 @@ const rtlBreadcrumbItems: BreadcrumbItem[] = [
29
29
 
30
30
  export function BreadcrumbsDemo() {
31
31
  return (
32
- <div className="grid gap-4">
33
- <Breadcrumbs aria-label="Breadcrumb" items={breadcrumbItems} overflowLabel="More" />
32
+ <div className="grid gap-[var(--bh-space-3xl-16)]">
33
+ <Breadcrumbs aria-label="Default breadcrumb" items={breadcrumbItems} overflowLabel="More" />
34
34
  <Breadcrumbs
35
- aria-label="Breadcrumb"
35
+ aria-label="Raised breadcrumb"
36
36
  items={breadcrumbItems}
37
37
  overflowLabel="More"
38
38
  separator="chevron"
39
39
  style="raised"
40
40
  />
41
41
  <Breadcrumbs
42
- aria-label="Breadcrumb"
42
+ aria-label="Collapsed breadcrumb"
43
43
  items={longBreadcrumbItems}
44
44
  maxItems={4}
45
45
  overflowLabel="More"
@@ -19,7 +19,7 @@ const inboxActions: EmptyStateAction[] = [
19
19
 
20
20
  export function EmptyStateDemo() {
21
21
  return (
22
- <div className="grid gap-6">
22
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
23
23
  <EmptyState
24
24
  actions={searchActions}
25
25
  description="Try adjusting your search or filters"
@@ -37,7 +37,7 @@ const uploadFiles: FileUploadFile[] = [
37
37
 
38
38
  export function FileUploadDemo() {
39
39
  return (
40
- <div className="grid items-start gap-5 xl:grid-cols-2">
40
+ <div className="grid items-start gap-[var(--bh-space-4xl-20)] xl:grid-cols-2">
41
41
  <FileUpload
42
42
  files={uploadFiles}
43
43
  multiple
@@ -2,7 +2,7 @@ import { OnboardingStepListItem } from "@/components/ui/expanded/OnboardingStepL
2
2
 
3
3
  export function OnboardingStepDemo() {
4
4
  return (
5
- <div className="flex gap-2">
5
+ <div className="flex gap-[var(--bh-space-md-8)]">
6
6
  <OnboardingStepListItem label="Finished" state="finished" />
7
7
  <OnboardingStepListItem label="Active" state="active" />
8
8
  <OnboardingStepListItem label="Inactive" state="inactive" />
@@ -1,4 +1,4 @@
1
- import { Slideout, SlideoutFiltersExample } from "@/components/ui/expanded/Slideout"
1
+ import { Slideout } from "@/components/ui/expanded/Slideout"
2
2
 
3
3
  export function SlideoutDemo() {
4
4
  return (
@@ -9,7 +9,7 @@ export function SlideoutDemo() {
9
9
  secondaryActionLabel="Cancel"
10
10
  title="Heading"
11
11
  >
12
- <SlideoutFiltersExample />
12
+ <p>Slideout content</p>
13
13
  </Slideout>
14
14
  )
15
15
  }
@@ -21,7 +21,7 @@ const stepItems: StepItem[] = Array.from({ length: 6 }, (_, index) => ({
21
21
 
22
22
  export function StepsDemo() {
23
23
  return (
24
- <div className="grid gap-8">
24
+ <div className="grid gap-[var(--bh-space-6xl-32)]">
25
25
  <Steps items={stepItems} />
26
26
  <Steps direction="vertical" items={stepItems} />
27
27
  </div>
@@ -4,7 +4,7 @@ const tabItems = ["Overview", "Details", "Settings", "Activity", "Files"]
4
4
 
5
5
  export function TabsDemo() {
6
6
  return (
7
- <div className="grid gap-6">
7
+ <div className="grid gap-[var(--bh-space-5xl-24)]">
8
8
  <Tabs ariaLabel="Tabs" items={tabItems} />
9
9
  <Tabs ariaLabel="Tabs" items={tabItems} variant="segment" />
10
10
  <Tabs ariaLabel="Tabs" items={tabItems} variant="rounded" />
@@ -10,7 +10,7 @@ const timelineSteps: TimelineStep[] = Array.from({ length: 6 }, (_, index) => ({
10
10
 
11
11
  export function TimelineDemo() {
12
12
  return (
13
- <div className="grid gap-8">
13
+ <div className="grid gap-[var(--bh-space-6xl-32)]">
14
14
  <Timeline ariaLabel="Timeline" steps={timelineSteps} />
15
15
  <Timeline ariaLabel="Timeline" orientation="horizontal" steps={timelineSteps} />
16
16
  </div>
@@ -7,11 +7,11 @@ import {
7
7
  export function HoverCardDemo() {
8
8
  return (
9
9
  <HoverCard>
10
- <HoverCardTrigger className="underline underline-offset-4">
10
+ <HoverCardTrigger className="underline underline-offset-[var(--bh-space-xs-4)]">
11
11
  Workspace profile
12
12
  </HoverCardTrigger>
13
13
  <HoverCardContent>
14
- <div className="grid gap-1">
14
+ <div className="grid gap-[var(--bh-space-xs-4)]">
15
15
  <strong>Design System</strong>
16
16
  <span className="text-sm text-[var(--bh-content-subtle)]">
17
17
  Tokens, components, and RTL-ready examples.