banhaten 0.1.2 → 0.1.3

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 (231) hide show
  1. package/README.md +93 -328
  2. package/banhaten.config.example.json +1 -1
  3. package/docs/design-system/README.md +11 -0
  4. package/docs/design-system/appearance-presets.md +184 -0
  5. package/docs/design-system/appearances/default.md +94 -0
  6. package/docs/design-system/appearances/rounded.md +95 -0
  7. package/docs/design-system/appearances/sharp.md +95 -0
  8. package/docs/design-system/component-showcase-consistency-report.md +217 -0
  9. package/docs/design-system/component-token-consistency-audit.md +163 -0
  10. package/docs/design-system/components/README.md +74 -0
  11. package/docs/design-system/components/accordion.md +51 -0
  12. package/docs/design-system/components/activity-feed.md +92 -0
  13. package/docs/design-system/components/alert-dialog.md +70 -0
  14. package/docs/design-system/components/alert.md +79 -0
  15. package/docs/design-system/components/aspect-ratio.md +44 -0
  16. package/docs/design-system/components/attribute.md +87 -0
  17. package/docs/design-system/components/autocomplete.md +74 -0
  18. package/docs/design-system/components/avatar.md +52 -0
  19. package/docs/design-system/components/badge.md +53 -0
  20. package/docs/design-system/components/banner.md +85 -0
  21. package/docs/design-system/components/breadcrumbs.md +174 -0
  22. package/docs/design-system/components/button-group.md +83 -0
  23. package/docs/design-system/components/button.md +77 -0
  24. package/docs/design-system/components/card.md +78 -0
  25. package/docs/design-system/components/carousel.md +44 -0
  26. package/docs/design-system/components/catalog-components.md +45 -0
  27. package/docs/design-system/components/chart.md +43 -0
  28. package/docs/design-system/components/checkbox.md +52 -0
  29. package/docs/design-system/components/collapsible.md +48 -0
  30. package/docs/design-system/components/command-bar.md +57 -0
  31. package/docs/design-system/components/command.md +60 -0
  32. package/docs/design-system/components/context-menu.md +44 -0
  33. package/docs/design-system/components/date-picker.md +77 -0
  34. package/docs/design-system/components/divider.md +101 -0
  35. package/docs/design-system/components/empty-state.md +55 -0
  36. package/docs/design-system/components/field.md +69 -0
  37. package/docs/design-system/components/file-upload.md +185 -0
  38. package/docs/design-system/components/hover-card.md +46 -0
  39. package/docs/design-system/components/icons.md +48 -0
  40. package/docs/design-system/components/input-group.md +56 -0
  41. package/docs/design-system/components/input-otp.md +55 -0
  42. package/docs/design-system/components/input.md +48 -0
  43. package/docs/design-system/components/kbd.md +44 -0
  44. package/docs/design-system/components/label.md +48 -0
  45. package/docs/design-system/components/menu.md +59 -0
  46. package/docs/design-system/components/menubar.md +45 -0
  47. package/docs/design-system/components/modal.md +98 -0
  48. package/docs/design-system/components/native-select.md +52 -0
  49. package/docs/design-system/components/navigation-menu.md +48 -0
  50. package/docs/design-system/components/onboarding-step-list-item.md +80 -0
  51. package/docs/design-system/components/page-header.md +84 -0
  52. package/docs/design-system/components/pagination.md +49 -0
  53. package/docs/design-system/components/popover.md +58 -0
  54. package/docs/design-system/components/progress-slider.md +48 -0
  55. package/docs/design-system/components/progress.md +75 -0
  56. package/docs/design-system/components/radio-card.md +49 -0
  57. package/docs/design-system/components/radio-group.md +55 -0
  58. package/docs/design-system/components/resizable.md +42 -0
  59. package/docs/design-system/components/scroll-area.md +45 -0
  60. package/docs/design-system/components/select.md +50 -0
  61. package/docs/design-system/components/sheet.md +65 -0
  62. package/docs/design-system/components/sidebar.md +68 -0
  63. package/docs/design-system/components/skeleton.md +73 -0
  64. package/docs/design-system/components/slideout.md +63 -0
  65. package/docs/design-system/components/slider.md +61 -0
  66. package/docs/design-system/components/social-button.md +47 -0
  67. package/docs/design-system/components/spinner.md +61 -0
  68. package/docs/design-system/components/steps.md +63 -0
  69. package/docs/design-system/components/table.md +397 -0
  70. package/docs/design-system/components/tabs.md +52 -0
  71. package/docs/design-system/components/tag.md +78 -0
  72. package/docs/design-system/components/textarea.md +48 -0
  73. package/docs/design-system/components/timeline.md +81 -0
  74. package/docs/design-system/components/toast.md +56 -0
  75. package/docs/design-system/components/toggle.md +79 -0
  76. package/docs/design-system/components/toolbar.md +85 -0
  77. package/docs/design-system/components/tooltip.md +90 -0
  78. package/docs/design-system/components/typography.md +18 -0
  79. package/docs/design-system/design-system-test-missing-items.md +368 -0
  80. package/docs/design-system/icons.md +69 -0
  81. package/docs/design-system/registry-and-cli.md +41 -0
  82. package/docs/design-system/tabs.md +53 -0
  83. package/docs/design-system/token-governance.md +38 -0
  84. package/package.json +83 -65
  85. package/registry/components/alert-dialog.tsx +297 -0
  86. package/registry/components/aspect-ratio.tsx +30 -0
  87. package/registry/components/carousel.tsx +234 -0
  88. package/registry/components/chart.tsx +170 -0
  89. package/registry/components/collapsible.tsx +69 -0
  90. package/registry/components/command.tsx +174 -0
  91. package/registry/components/context-menu.tsx +236 -0
  92. package/registry/components/date-picker.tsx +1 -1
  93. package/registry/components/expanded/PageHeader.tsx +1 -1
  94. package/registry/components/expanded/breadcrumbs.css +139 -139
  95. package/registry/components/expanded/catalogComponentsShowcase.css +83 -83
  96. package/registry/components/expanded/steps.css +274 -274
  97. package/registry/components/expanded/timeline.css +264 -264
  98. package/registry/components/field.tsx +230 -0
  99. package/registry/components/hover-card.tsx +48 -0
  100. package/registry/components/input-group.tsx +130 -0
  101. package/registry/components/input.tsx +2 -2
  102. package/registry/components/kbd.tsx +44 -0
  103. package/registry/components/label.tsx +78 -0
  104. package/registry/components/menu.tsx +3 -1
  105. package/registry/components/menubar.tsx +226 -0
  106. package/registry/components/modal.tsx +109 -76
  107. package/registry/components/native-select.tsx +205 -0
  108. package/registry/components/navigation-menu.tsx +171 -0
  109. package/registry/components/radio-group.tsx +1 -1
  110. package/registry/components/resizable.tsx +74 -0
  111. package/registry/components/scroll-area.tsx +67 -0
  112. package/registry/components/select.tsx +2 -4
  113. package/registry/components/sheet.tsx +305 -0
  114. package/registry/components/sidebar.tsx +352 -0
  115. package/registry/components/social-button.tsx +74 -10
  116. package/registry/components/{expanded/tabs.css → tabs.css} +127 -106
  117. package/registry/components/tabs.tsx +242 -0
  118. package/registry/components/textarea.tsx +1 -1
  119. package/registry/components/toast.tsx +131 -0
  120. package/registry/examples/alert-dialog-demo.tsx +42 -0
  121. package/registry/examples/aspect-ratio-demo.tsx +11 -0
  122. package/registry/examples/carousel-demo.tsx +25 -0
  123. package/registry/examples/chart-demo.tsx +33 -0
  124. package/registry/examples/collapsible-demo.tsx +16 -0
  125. package/registry/examples/command-demo.tsx +42 -0
  126. package/registry/examples/context-menu-demo.tsx +29 -0
  127. package/registry/examples/expanded/tabs-demo.tsx +1 -1
  128. package/registry/examples/field-demo.tsx +51 -0
  129. package/registry/examples/hover-card-demo.tsx +23 -0
  130. package/registry/examples/input-group-demo.tsx +16 -0
  131. package/registry/examples/kbd-demo.tsx +11 -0
  132. package/registry/examples/label-demo.tsx +20 -0
  133. package/registry/examples/menubar-demo.tsx +34 -0
  134. package/registry/examples/native-select-demo.tsx +16 -0
  135. package/registry/examples/navigation-menu-demo.tsx +29 -0
  136. package/registry/examples/resizable-demo.tsx +22 -0
  137. package/registry/examples/scroll-area-demo.tsx +15 -0
  138. package/registry/examples/sheet-demo.tsx +47 -0
  139. package/registry/examples/sidebar-demo.tsx +55 -0
  140. package/registry/examples/tabs-demo.tsx +13 -0
  141. package/registry/examples/toast-demo.tsx +35 -0
  142. package/registry/index.json +655 -11
  143. package/registry/styles/globals.css +4733 -4690
  144. package/registry.json +1612 -0
  145. package/schema/config.schema.json +48 -0
  146. package/schema/registry.schema.json +85 -0
  147. package/schema/tokens.schema.json +63 -0
  148. package/src/cli/index.js +312 -18
  149. package/tokens/banhaten.tokens.json +1 -1
  150. package/registry/assets/avatars/avatar-02.jpg +0 -0
  151. package/registry/assets/avatars/avatar-03.jpg +0 -0
  152. package/registry/assets/avatars/avatar-04.jpg +0 -0
  153. package/registry/assets/avatars/avatar-05.jpg +0 -0
  154. package/registry/assets/avatars/avatar-06.jpg +0 -0
  155. package/registry/assets/avatars/avatar-07.jpg +0 -0
  156. package/registry/assets/avatars/avatar-08.jpg +0 -0
  157. package/registry/assets/avatars/avatar-09.jpg +0 -0
  158. package/registry/assets/avatars/avatar-10.jpg +0 -0
  159. package/registry/assets/avatars/avatar-11.jpg +0 -0
  160. package/registry/assets/avatars/avatar-12.jpg +0 -0
  161. package/registry/assets/avatars/avatar-13.jpg +0 -0
  162. package/registry/assets/avatars/avatar-14.jpg +0 -0
  163. package/registry/assets/avatars/avatar-15.jpg +0 -0
  164. package/registry/assets/avatars/avatar-16.jpg +0 -0
  165. package/registry/assets/avatars/avatar-17.jpg +0 -0
  166. package/registry/assets/avatars/avatar-18.jpg +0 -0
  167. package/registry/assets/avatars/avatar-19.jpg +0 -0
  168. package/registry/assets/avatars/avatar-20.jpg +0 -0
  169. package/registry/assets/avatars/avatar-21.jpg +0 -0
  170. package/registry/assets/avatars/avatar-22.jpg +0 -0
  171. package/registry/assets/avatars/avatar-23.jpg +0 -0
  172. package/registry/assets/avatars/avatar-24.jpg +0 -0
  173. package/registry/assets/avatars/avatar-25.jpg +0 -0
  174. package/registry/assets/avatars/avatar-26.jpg +0 -0
  175. package/registry/assets/avatars/avatar-27.jpg +0 -0
  176. package/registry/assets/avatars/avatar-28.jpg +0 -0
  177. package/registry/assets/avatars/avatar-29.jpg +0 -0
  178. package/registry/assets/avatars/avatar-30.jpg +0 -0
  179. package/registry/assets/avatars/avatar-31.jpg +0 -0
  180. package/registry/assets/avatars/avatar-32.jpg +0 -0
  181. package/registry/assets/avatars/avatar-33.jpg +0 -0
  182. package/registry/assets/avatars/avatar-34.jpg +0 -0
  183. package/registry/assets/avatars/avatar-35.jpg +0 -0
  184. package/registry/assets/image-assets.json +0 -744
  185. package/registry/assets/images/art-02.jpg +0 -0
  186. package/registry/assets/images/art-03.jpg +0 -0
  187. package/registry/assets/images/art-04.jpg +0 -0
  188. package/registry/assets/images/art-05.jpg +0 -0
  189. package/registry/assets/images/art-06.jpg +0 -0
  190. package/registry/assets/images/art-07.jpg +0 -0
  191. package/registry/assets/images/art-08.jpg +0 -0
  192. package/registry/assets/images/art-09.jpg +0 -0
  193. package/registry/assets/images/art-10.jpg +0 -0
  194. package/registry/assets/images/art-11.jpg +0 -0
  195. package/registry/assets/images/art-12.jpg +0 -0
  196. package/registry/assets/images/art-13.jpg +0 -0
  197. package/registry/assets/images/art-14.jpg +0 -0
  198. package/registry/assets/images/art-15.jpg +0 -0
  199. package/registry/assets/images/art-16.jpg +0 -0
  200. package/registry/assets/images/art-17.jpg +0 -0
  201. package/registry/assets/images/art-18.jpg +0 -0
  202. package/registry/assets/images/art-19.jpg +0 -0
  203. package/registry/assets/images/art-20.jpg +0 -0
  204. package/registry/assets/images/art-21.jpg +0 -0
  205. package/registry/assets/images/art-22.jpg +0 -0
  206. package/registry/assets/images/art-23.jpg +0 -0
  207. package/registry/assets/images/art-24.jpg +0 -0
  208. package/registry/assets/images/art-25.jpg +0 -0
  209. package/registry/assets/images/art-26.jpg +0 -0
  210. package/registry/assets/images/art-27.jpg +0 -0
  211. package/registry/assets/images/nature-01.jpg +0 -0
  212. package/registry/assets/images/nature-02.jpg +0 -0
  213. package/registry/assets/images/nature-03.jpg +0 -0
  214. package/registry/assets/images/nature-04.jpg +0 -0
  215. package/registry/assets/images/nature-05.jpg +0 -0
  216. package/registry/assets/images/nature-06.jpg +0 -0
  217. package/registry/assets/images/nature-07.jpg +0 -0
  218. package/registry/assets/images/nature-08.jpg +0 -0
  219. package/registry/assets/images/nature-09.jpg +0 -0
  220. package/registry/assets/images/nature-10.jpg +0 -0
  221. package/registry/assets/images/nature-11.jpg +0 -0
  222. package/registry/assets/images/nature-12.jpg +0 -0
  223. package/registry/assets/images/nature-13.jpg +0 -0
  224. package/registry/assets/images/nature-14.jpg +0 -0
  225. package/registry/assets/images/nature-15.jpg +0 -0
  226. package/registry/assets/images/nature-16.jpg +0 -0
  227. package/registry/assets/images/nature-17.jpg +0 -0
  228. package/registry/assets/images/nature-18.jpg +0 -0
  229. package/registry/assets/images/nature-19.jpg +0 -0
  230. package/registry/assets/images/nature-20.jpg +0 -0
  231. package/registry/components/expanded/Tabs.tsx +0 -86
@@ -0,0 +1,234 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import useEmblaCarousel, {
5
+ type UseEmblaCarouselType,
6
+ } from "embla-carousel-react"
7
+ import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react"
8
+
9
+ import { Button } from "@/components/ui/button"
10
+ import { cn } from "@/lib/utils"
11
+
12
+ type CarouselApi = UseEmblaCarouselType[1]
13
+ type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
14
+ type CarouselOptions = UseCarouselParameters[0]
15
+ type CarouselPlugin = UseCarouselParameters[1]
16
+ type CarouselOrientation = "horizontal" | "vertical"
17
+
18
+ type CarouselProps = React.ComponentProps<"div"> & {
19
+ opts?: CarouselOptions
20
+ orientation?: CarouselOrientation
21
+ plugins?: CarouselPlugin
22
+ setApi?: (api: CarouselApi) => void
23
+ }
24
+ type CarouselContentProps = React.ComponentProps<"div">
25
+ type CarouselItemProps = React.ComponentProps<"div">
26
+ type CarouselButtonProps = React.ComponentProps<typeof Button>
27
+
28
+ type CarouselContextValue = {
29
+ api: CarouselApi
30
+ canScrollNext: boolean
31
+ canScrollPrev: boolean
32
+ orientation: CarouselOrientation
33
+ scrollNext: () => void
34
+ scrollPrev: () => void
35
+ }
36
+
37
+ const CarouselContext = React.createContext<CarouselContextValue | null>(null)
38
+
39
+ const Carousel = React.forwardRef<HTMLDivElement, CarouselProps>(
40
+ function Carousel(
41
+ {
42
+ children,
43
+ className,
44
+ opts,
45
+ orientation = "horizontal",
46
+ plugins,
47
+ setApi,
48
+ ...props
49
+ },
50
+ ref
51
+ ) {
52
+ const [carouselRef, api] = useEmblaCarousel(
53
+ {
54
+ ...opts,
55
+ axis: orientation === "horizontal" ? "x" : "y",
56
+ },
57
+ plugins
58
+ )
59
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false)
60
+ const [canScrollNext, setCanScrollNext] = React.useState(false)
61
+
62
+ const onSelect = React.useCallback((nextApi: CarouselApi) => {
63
+ if (!nextApi) return
64
+ setCanScrollPrev(nextApi.canScrollPrev())
65
+ setCanScrollNext(nextApi.canScrollNext())
66
+ }, [])
67
+
68
+ const scrollPrev = React.useCallback(() => api?.scrollPrev(), [api])
69
+ const scrollNext = React.useCallback(() => api?.scrollNext(), [api])
70
+
71
+ React.useEffect(() => {
72
+ if (!api) return
73
+ setApi?.(api)
74
+ onSelect(api)
75
+ api.on("reInit", onSelect)
76
+ api.on("select", onSelect)
77
+
78
+ return () => {
79
+ api.off("select", onSelect)
80
+ }
81
+ }, [api, onSelect, setApi])
82
+
83
+ return (
84
+ <CarouselContext.Provider
85
+ value={{
86
+ api,
87
+ canScrollNext,
88
+ canScrollPrev,
89
+ orientation,
90
+ scrollNext,
91
+ scrollPrev,
92
+ }}
93
+ >
94
+ <div
95
+ data-orientation={orientation}
96
+ data-slot="carousel"
97
+ ref={ref}
98
+ role="region"
99
+ className={cn("relative", className)}
100
+ {...props}
101
+ >
102
+ <div ref={carouselRef} className="overflow-hidden">
103
+ {children}
104
+ </div>
105
+ </div>
106
+ </CarouselContext.Provider>
107
+ )
108
+ }
109
+ )
110
+
111
+ const CarouselContent = React.forwardRef<HTMLDivElement, CarouselContentProps>(
112
+ function CarouselContent({ className, ...props }, ref) {
113
+ const { orientation } = useCarousel()
114
+
115
+ return (
116
+ <div
117
+ data-slot="carousel-content"
118
+ ref={ref}
119
+ className={cn(
120
+ "flex",
121
+ orientation === "horizontal"
122
+ ? "-ms-[var(--bh-space-3xl-16)]"
123
+ : "-mt-[var(--bh-space-3xl-16)] flex-col",
124
+ className
125
+ )}
126
+ {...props}
127
+ />
128
+ )
129
+ }
130
+ )
131
+
132
+ const CarouselItem = React.forwardRef<HTMLDivElement, CarouselItemProps>(
133
+ function CarouselItem({ className, ...props }, ref) {
134
+ const { orientation } = useCarousel()
135
+
136
+ return (
137
+ <div
138
+ data-slot="carousel-item"
139
+ ref={ref}
140
+ role="group"
141
+ className={cn(
142
+ "min-w-0 shrink-0 grow-0 basis-full",
143
+ orientation === "horizontal"
144
+ ? "ps-[var(--bh-space-3xl-16)]"
145
+ : "pt-[var(--bh-space-3xl-16)]",
146
+ className
147
+ )}
148
+ {...props}
149
+ />
150
+ )
151
+ }
152
+ )
153
+
154
+ const CarouselPrevious = React.forwardRef<HTMLButtonElement, CarouselButtonProps>(
155
+ function CarouselPrevious({ className, variant = "outline", size = "icon", ...props }, ref) {
156
+ const { canScrollPrev, orientation, scrollPrev } = useCarousel()
157
+
158
+ return (
159
+ <Button
160
+ aria-label="Previous slide"
161
+ className={cn(
162
+ "absolute size-[var(--bh-space-7xl-40)] rounded-[var(--bh-radius-full)]",
163
+ orientation === "horizontal"
164
+ ? "start-[calc(var(--bh-space-8xl-48)*-1)] top-1/2 -translate-y-1/2"
165
+ : "start-1/2 top-[calc(var(--bh-space-8xl-48)*-1)] -translate-x-1/2 rotate-90",
166
+ className
167
+ )}
168
+ disabled={!canScrollPrev}
169
+ onClick={scrollPrev}
170
+ ref={ref}
171
+ size={size}
172
+ type="button"
173
+ variant={variant}
174
+ {...props}
175
+ >
176
+ <ArrowLeftIcon className="size-[var(--bh-space-3xl-16)] rtl:-scale-x-100" />
177
+ </Button>
178
+ )
179
+ }
180
+ )
181
+
182
+ const CarouselNext = React.forwardRef<HTMLButtonElement, CarouselButtonProps>(
183
+ function CarouselNext({ className, variant = "outline", size = "icon", ...props }, ref) {
184
+ const { canScrollNext, orientation, scrollNext } = useCarousel()
185
+
186
+ return (
187
+ <Button
188
+ aria-label="Next slide"
189
+ className={cn(
190
+ "absolute size-[var(--bh-space-7xl-40)] rounded-[var(--bh-radius-full)]",
191
+ orientation === "horizontal"
192
+ ? "end-[calc(var(--bh-space-8xl-48)*-1)] top-1/2 -translate-y-1/2"
193
+ : "bottom-[calc(var(--bh-space-8xl-48)*-1)] start-1/2 -translate-x-1/2 rotate-90",
194
+ className
195
+ )}
196
+ disabled={!canScrollNext}
197
+ onClick={scrollNext}
198
+ ref={ref}
199
+ size={size}
200
+ type="button"
201
+ variant={variant}
202
+ {...props}
203
+ >
204
+ <ArrowRightIcon className="size-[var(--bh-space-3xl-16)] rtl:-scale-x-100" />
205
+ </Button>
206
+ )
207
+ }
208
+ )
209
+
210
+ function useCarousel() {
211
+ const context = React.useContext(CarouselContext)
212
+ if (!context) {
213
+ throw new Error("Carousel parts must be used within Carousel")
214
+ }
215
+ return context
216
+ }
217
+
218
+ export {
219
+ Carousel,
220
+ CarouselContent,
221
+ CarouselItem,
222
+ CarouselNext,
223
+ CarouselPrevious,
224
+ }
225
+ export type {
226
+ CarouselApi,
227
+ CarouselButtonProps,
228
+ CarouselContentProps,
229
+ CarouselItemProps,
230
+ CarouselOptions,
231
+ CarouselOrientation,
232
+ CarouselPlugin,
233
+ CarouselProps,
234
+ }
@@ -0,0 +1,170 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import {
5
+ Legend as RechartsLegend,
6
+ ResponsiveContainer,
7
+ Tooltip as RechartsTooltip,
8
+ } from "recharts"
9
+
10
+ import { cn } from "@/lib/utils"
11
+
12
+ type ChartConfig = Record<
13
+ string,
14
+ {
15
+ color?: string
16
+ label?: React.ReactNode
17
+ }
18
+ >
19
+ type ChartContainerProps = React.ComponentProps<"div"> & {
20
+ config?: ChartConfig
21
+ }
22
+ type ChartTooltipProps = React.ComponentProps<typeof RechartsTooltip>
23
+ type ChartLegendProps = React.ComponentProps<typeof RechartsLegend>
24
+ type ChartPayloadItem = {
25
+ color?: string
26
+ dataKey?: string | number
27
+ name?: React.ReactNode
28
+ value?: React.ReactNode
29
+ }
30
+ type ChartTooltipContentProps = React.ComponentProps<"div"> & {
31
+ active?: boolean
32
+ hideLabel?: boolean
33
+ label?: React.ReactNode
34
+ payload?: ChartPayloadItem[]
35
+ }
36
+ type ChartLegendContentProps = React.ComponentProps<"div"> & {
37
+ payload?: ChartPayloadItem[]
38
+ }
39
+
40
+ function ChartContainer({
41
+ children,
42
+ className,
43
+ config,
44
+ style,
45
+ ...props
46
+ }: ChartContainerProps) {
47
+ return (
48
+ <div
49
+ data-slot="chart"
50
+ style={{ ...getChartStyle(config), ...style }}
51
+ className={cn(
52
+ "h-[var(--bh-space-19xl-384)] w-full text-[length:var(--bh-text-body-xs-regular-font-size)] text-[var(--bh-content-subtle)] [&_.recharts-cartesian-axis-tick_text]:fill-[var(--bh-content-muted)] [&_.recharts-cartesian-grid_line]:stroke-[var(--bh-border-subtle)] [&_.recharts-tooltip-cursor]:fill-[var(--bh-bg-neutral-subtle)]",
53
+ className
54
+ )}
55
+ {...props}
56
+ >
57
+ <ResponsiveContainer>{children}</ResponsiveContainer>
58
+ </div>
59
+ )
60
+ }
61
+
62
+ const ChartTooltip = RechartsTooltip
63
+ const ChartLegend = RechartsLegend
64
+
65
+ function ChartTooltipContent({
66
+ active,
67
+ className,
68
+ hideLabel = false,
69
+ label,
70
+ payload,
71
+ ...props
72
+ }: ChartTooltipContentProps) {
73
+ if (!active || !payload?.length) return null
74
+
75
+ return (
76
+ <div
77
+ data-slot="chart-tooltip"
78
+ className={cn(
79
+ "grid min-w-[var(--bh-space-17xl-288)] gap-[var(--bh-space-sm-6)] rounded-[var(--bh-radius-lg-8)] bg-[var(--bh-bg-raised)] p-[var(--bh-space-xl-12)] text-[length:var(--bh-text-body-xs-regular-font-size)] font-[var(--bh-text-body-xs-regular-font-weight)] leading-[var(--bh-text-body-xs-regular-line-height)] tracking-[var(--bh-text-body-xs-regular-letter-spacing)] text-[var(--bh-content-default)] shadow-[var(--shadow-popover)]",
80
+ className
81
+ )}
82
+ {...props}
83
+ >
84
+ {!hideLabel && label ? (
85
+ <div className="font-[var(--bh-text-body-xs-medium-font-weight)]">
86
+ {label}
87
+ </div>
88
+ ) : null}
89
+ <div className="grid gap-[var(--bh-space-xs-4)]">
90
+ {payload.map((item, index) => (
91
+ <div
92
+ key={`${String(item.dataKey ?? item.name)}-${index}`}
93
+ className="flex items-center gap-[var(--bh-space-md-8)]"
94
+ >
95
+ <span
96
+ aria-hidden="true"
97
+ className="size-[var(--bh-space-md-8)] shrink-0 rounded-[var(--bh-radius-full)]"
98
+ style={{ backgroundColor: item.color }}
99
+ />
100
+ <span className="min-w-0 flex-1 text-[var(--bh-content-subtle)]">
101
+ {item.name}
102
+ </span>
103
+ <span className="font-[var(--bh-text-body-xs-medium-font-weight)]">
104
+ {item.value}
105
+ </span>
106
+ </div>
107
+ ))}
108
+ </div>
109
+ </div>
110
+ )
111
+ }
112
+
113
+ function ChartLegendContent({
114
+ className,
115
+ payload,
116
+ ...props
117
+ }: ChartLegendContentProps) {
118
+ if (!payload?.length) return null
119
+
120
+ return (
121
+ <div
122
+ data-slot="chart-legend"
123
+ className={cn("flex flex-wrap items-center justify-center gap-[var(--bh-space-3xl-16)]", className)}
124
+ {...props}
125
+ >
126
+ {payload.map((item, index) => (
127
+ <div
128
+ key={`${String(item.dataKey ?? item.name)}-${index}`}
129
+ className="inline-flex items-center gap-[var(--bh-space-xs-4)] text-[length:var(--bh-text-body-xs-medium-font-size)] font-[var(--bh-text-body-xs-medium-font-weight)] text-[var(--bh-content-subtle)]"
130
+ >
131
+ <span
132
+ aria-hidden="true"
133
+ className="size-[var(--bh-space-md-8)] rounded-[var(--bh-radius-full)]"
134
+ style={{ backgroundColor: item.color }}
135
+ />
136
+ {item.value ?? item.name}
137
+ </div>
138
+ ))}
139
+ </div>
140
+ )
141
+ }
142
+
143
+ function getChartStyle(config?: ChartConfig): React.CSSProperties {
144
+ if (!config) return {}
145
+
146
+ return Object.entries(config).reduce<React.CSSProperties>(
147
+ (style, [key, value], index) => ({
148
+ ...style,
149
+ [`--color-${key}`]: value.color ?? `var(--bh-chart-${(index % 5) + 1})`,
150
+ }),
151
+ {}
152
+ )
153
+ }
154
+
155
+ export {
156
+ ChartContainer,
157
+ ChartLegend,
158
+ ChartLegendContent,
159
+ ChartTooltip,
160
+ ChartTooltipContent,
161
+ }
162
+ export type {
163
+ ChartConfig,
164
+ ChartContainerProps,
165
+ ChartLegendContentProps,
166
+ ChartLegendProps,
167
+ ChartPayloadItem,
168
+ ChartTooltipContentProps,
169
+ ChartTooltipProps,
170
+ }
@@ -0,0 +1,69 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
5
+ import { ChevronDownIcon } from "lucide-react"
6
+
7
+ import { cn } from "@/lib/utils"
8
+
9
+ type CollapsibleProps = React.ComponentProps<typeof CollapsiblePrimitive.Root>
10
+ type CollapsibleTriggerProps = React.ComponentPropsWithoutRef<
11
+ typeof CollapsiblePrimitive.Trigger
12
+ >
13
+ type CollapsibleContentProps = React.ComponentPropsWithoutRef<
14
+ typeof CollapsiblePrimitive.Content
15
+ >
16
+
17
+ const Collapsible = CollapsiblePrimitive.Root
18
+
19
+ const CollapsibleTrigger = React.forwardRef<
20
+ React.ElementRef<typeof CollapsiblePrimitive.Trigger>,
21
+ CollapsibleTriggerProps
22
+ >(function CollapsibleTrigger({ children, className, ...props }, ref) {
23
+ return (
24
+ <CollapsiblePrimitive.Trigger
25
+ data-slot="collapsible-trigger"
26
+ ref={ref}
27
+ className={cn(
28
+ "group/collapsible-trigger flex w-full items-center justify-between gap-[var(--bh-space-md-8)] rounded-[var(--bh-radius-lg-8)] px-[var(--bh-space-xl-12)] py-[var(--bh-space-lg-10)] text-start",
29
+ "text-[length:var(--bh-text-body-md-medium-font-size)] font-[var(--bh-text-body-md-medium-font-weight)] leading-[var(--bh-text-body-md-medium-line-height)] tracking-[var(--bh-text-body-md-medium-letter-spacing)] text-[var(--bh-content-default)]",
30
+ "outline-none transition-[background-color,box-shadow,color] hover:bg-[var(--bh-interactive-ghost-hover)] focus-visible:shadow-[var(--shadow-button-focus)]",
31
+ className
32
+ )}
33
+ {...props}
34
+ >
35
+ <span className="min-w-0 flex-1" dir="auto">
36
+ {children}
37
+ </span>
38
+ <ChevronDownIcon
39
+ aria-hidden="true"
40
+ className="size-[var(--bh-space-3xl-16)] shrink-0 text-[var(--bh-content-subtle)] transition-transform group-data-[state=open]/collapsible-trigger:rotate-180"
41
+ strokeWidth={2}
42
+ />
43
+ </CollapsiblePrimitive.Trigger>
44
+ )
45
+ })
46
+
47
+ const CollapsibleContent = React.forwardRef<
48
+ React.ElementRef<typeof CollapsiblePrimitive.Content>,
49
+ CollapsibleContentProps
50
+ >(function CollapsibleContent({ className, ...props }, ref) {
51
+ return (
52
+ <CollapsiblePrimitive.Content
53
+ data-slot="collapsible-content"
54
+ ref={ref}
55
+ className={cn(
56
+ "overflow-hidden px-[var(--bh-space-xl-12)] pb-[var(--bh-space-xl-12)] text-start text-[length:var(--bh-text-body-sm-regular-font-size)] font-[var(--bh-text-body-sm-regular-font-weight)] leading-[var(--bh-text-body-sm-regular-line-height)] tracking-[var(--bh-text-body-sm-regular-letter-spacing)] text-[var(--bh-content-subtle)]",
57
+ className
58
+ )}
59
+ {...props}
60
+ />
61
+ )
62
+ })
63
+
64
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger }
65
+ export type {
66
+ CollapsibleContentProps,
67
+ CollapsibleProps,
68
+ CollapsibleTriggerProps,
69
+ }
@@ -0,0 +1,174 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Command as CommandPrimitive } from "cmdk"
5
+ import { SearchIcon } from "lucide-react"
6
+
7
+ import { cn } from "@/lib/utils"
8
+
9
+ type CommandProps = React.ComponentProps<typeof CommandPrimitive>
10
+ type CommandInputProps = React.ComponentProps<typeof CommandPrimitive.Input>
11
+ type CommandListProps = React.ComponentProps<typeof CommandPrimitive.List>
12
+ type CommandEmptyProps = React.ComponentProps<typeof CommandPrimitive.Empty>
13
+ type CommandGroupProps = React.ComponentProps<typeof CommandPrimitive.Group>
14
+ type CommandItemProps = React.ComponentProps<typeof CommandPrimitive.Item>
15
+ type CommandSeparatorProps = React.ComponentProps<
16
+ typeof CommandPrimitive.Separator
17
+ >
18
+ type CommandShortcutProps = React.ComponentProps<"span">
19
+
20
+ const Command = React.forwardRef<HTMLDivElement, CommandProps>(function Command(
21
+ { className, ...props },
22
+ ref
23
+ ) {
24
+ return (
25
+ <CommandPrimitive
26
+ data-slot="command"
27
+ ref={ref}
28
+ className={cn(
29
+ "flex w-full max-w-[var(--bh-space-19xl-384)] flex-col overflow-hidden rounded-[var(--bh-radius-2xl-12)] bg-[var(--bh-bg-raised)] text-[var(--bh-content-default)] shadow-[var(--shadow-menu)]",
30
+ className
31
+ )}
32
+ {...props}
33
+ />
34
+ )
35
+ })
36
+
37
+ const CommandInput = React.forwardRef<HTMLInputElement, CommandInputProps>(
38
+ function CommandInput({ className, placeholder = "Search or type a command", ...props }, ref) {
39
+ return (
40
+ <div
41
+ data-slot="command-input-wrapper"
42
+ className="flex h-[var(--bh-space-8xl-48)] items-center gap-[var(--bh-space-md-8)] border-b border-[var(--bh-border-subtle)] px-[var(--bh-space-3xl-16)]"
43
+ >
44
+ <SearchIcon
45
+ aria-hidden="true"
46
+ className="size-[var(--bh-space-5xl-24)] shrink-0 text-[var(--bh-content-muted)]"
47
+ strokeWidth={2}
48
+ />
49
+ <CommandPrimitive.Input
50
+ data-slot="command-input"
51
+ ref={ref}
52
+ placeholder={placeholder}
53
+ className={cn(
54
+ "h-full min-w-0 flex-1 border-0 bg-transparent p-0 text-start text-[length:var(--bh-text-body-md-regular-font-size)] font-[var(--bh-text-body-md-regular-font-weight)] leading-[var(--bh-text-body-md-regular-line-height)] tracking-[var(--bh-text-body-md-regular-letter-spacing)] text-[var(--bh-content-default)] outline-none placeholder:text-[var(--bh-content-muted)] disabled:cursor-not-allowed disabled:text-[var(--bh-content-disabled)]",
55
+ className
56
+ )}
57
+ {...props}
58
+ />
59
+ </div>
60
+ )
61
+ }
62
+ )
63
+
64
+ const CommandList = React.forwardRef<HTMLDivElement, CommandListProps>(
65
+ function CommandList({ className, ...props }, ref) {
66
+ return (
67
+ <CommandPrimitive.List
68
+ data-slot="command-list"
69
+ ref={ref}
70
+ className={cn(
71
+ "max-h-[calc(var(--bh-space-19xl-384)+var(--bh-space-8xl-48))] overflow-y-auto overflow-x-hidden p-[var(--bh-space-md-8)]",
72
+ className
73
+ )}
74
+ {...props}
75
+ />
76
+ )
77
+ }
78
+ )
79
+
80
+ const CommandEmpty = React.forwardRef<HTMLDivElement, CommandEmptyProps>(
81
+ function CommandEmpty({ className, ...props }, ref) {
82
+ return (
83
+ <CommandPrimitive.Empty
84
+ data-slot="command-empty"
85
+ ref={ref}
86
+ className={cn(
87
+ "py-[var(--bh-space-8xl-48)] text-center text-[length:var(--bh-text-body-sm-regular-font-size)] font-[var(--bh-text-body-sm-regular-font-weight)] leading-[var(--bh-text-body-sm-regular-line-height)] tracking-[var(--bh-text-body-sm-regular-letter-spacing)] text-[var(--bh-content-subtle)]",
88
+ className
89
+ )}
90
+ {...props}
91
+ />
92
+ )
93
+ }
94
+ )
95
+
96
+ const CommandGroup = React.forwardRef<HTMLDivElement, CommandGroupProps>(
97
+ function CommandGroup({ className, ...props }, ref) {
98
+ return (
99
+ <CommandPrimitive.Group
100
+ data-slot="command-group"
101
+ ref={ref}
102
+ className={cn(
103
+ "overflow-hidden p-[var(--bh-space-xs-4)] text-[var(--bh-content-default)] [&_[cmdk-group-heading]]:px-[var(--bh-space-md-8)] [&_[cmdk-group-heading]]:py-[var(--bh-space-sm-6)] [&_[cmdk-group-heading]]:text-[length:var(--bh-text-body-xs-medium-font-size)] [&_[cmdk-group-heading]]:font-[var(--bh-text-body-xs-medium-font-weight)] [&_[cmdk-group-heading]]:leading-[var(--bh-text-body-xs-medium-line-height)] [&_[cmdk-group-heading]]:tracking-[var(--bh-text-body-xs-medium-letter-spacing)] [&_[cmdk-group-heading]]:text-[var(--bh-content-muted)]",
104
+ className
105
+ )}
106
+ {...props}
107
+ />
108
+ )
109
+ }
110
+ )
111
+
112
+ const CommandItem = React.forwardRef<HTMLDivElement, CommandItemProps>(
113
+ function CommandItem({ className, ...props }, ref) {
114
+ return (
115
+ <CommandPrimitive.Item
116
+ data-slot="command-item"
117
+ ref={ref}
118
+ className={cn(
119
+ "relative flex min-h-[var(--bh-space-8xl-48)] cursor-default select-none items-center gap-[var(--bh-space-md-8)] rounded-[var(--bh-radius-lg-8)] px-[var(--bh-space-md-8)] py-[var(--bh-space-sm-6)] text-start text-[length:var(--bh-text-body-sm-medium-font-size)] font-[var(--bh-text-body-sm-medium-font-weight)] leading-[var(--bh-text-body-sm-medium-line-height)] tracking-[var(--bh-text-body-sm-medium-letter-spacing)] text-[var(--bh-content-default)] outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:text-[var(--bh-content-disabled)] data-[selected=true]:bg-[var(--bh-interactive-ghost-hover)]",
120
+ className
121
+ )}
122
+ {...props}
123
+ />
124
+ )
125
+ }
126
+ )
127
+
128
+ const CommandSeparator = React.forwardRef<
129
+ HTMLDivElement,
130
+ CommandSeparatorProps
131
+ >(function CommandSeparator({ className, ...props }, ref) {
132
+ return (
133
+ <CommandPrimitive.Separator
134
+ data-slot="command-separator"
135
+ ref={ref}
136
+ className={cn("-mx-[var(--bh-space-md-8)] my-[var(--bh-space-md-8)] h-[var(--bh-border-width-default)] bg-[var(--bh-border-subtle)]", className)}
137
+ {...props}
138
+ />
139
+ )
140
+ })
141
+
142
+ function CommandShortcut({ className, ...props }: CommandShortcutProps) {
143
+ return (
144
+ <span
145
+ data-slot="command-shortcut"
146
+ className={cn(
147
+ "ms-auto text-[length:var(--bh-text-body-xs-medium-font-size)] font-[var(--bh-text-body-xs-medium-font-weight)] leading-[var(--bh-text-body-xs-medium-line-height)] tracking-[var(--bh-text-body-xs-medium-letter-spacing)] text-[var(--bh-content-muted)]",
148
+ className
149
+ )}
150
+ {...props}
151
+ />
152
+ )
153
+ }
154
+
155
+ export {
156
+ Command,
157
+ CommandEmpty,
158
+ CommandGroup,
159
+ CommandInput,
160
+ CommandItem,
161
+ CommandList,
162
+ CommandSeparator,
163
+ CommandShortcut,
164
+ }
165
+ export type {
166
+ CommandEmptyProps,
167
+ CommandGroupProps,
168
+ CommandInputProps,
169
+ CommandItemProps,
170
+ CommandListProps,
171
+ CommandProps,
172
+ CommandSeparatorProps,
173
+ CommandShortcutProps,
174
+ }