arcway 0.1.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 (274) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +711 -0
  3. package/client/env.js +55 -0
  4. package/client/fetcher.js +50 -0
  5. package/client/graphql.js +35 -0
  6. package/client/head.js +140 -0
  7. package/client/hooks/use-api.js +80 -0
  8. package/client/hooks/use-debounce.js +12 -0
  9. package/client/hooks/use-form.js +86 -0
  10. package/client/hooks/use-graphql.js +30 -0
  11. package/client/hooks/use-interval.js +12 -0
  12. package/client/hooks/use-mutation.js +27 -0
  13. package/client/hooks/use-query.js +45 -0
  14. package/client/hooks/web/use-click-outside.js +22 -0
  15. package/client/hooks/web/use-local-storage.js +42 -0
  16. package/client/index.js +62 -0
  17. package/client/page-loader.js +155 -0
  18. package/client/provider.js +53 -0
  19. package/client/query.js +13 -0
  20. package/client/router.jsx +303 -0
  21. package/client/ui/accordion.jsx +65 -0
  22. package/client/ui/accordion.stories.jsx +48 -0
  23. package/client/ui/alert-dialog.jsx +122 -0
  24. package/client/ui/alert-dialog.stories.jsx +44 -0
  25. package/client/ui/alert.jsx +52 -0
  26. package/client/ui/alert.stories.jsx +31 -0
  27. package/client/ui/app-shell.jsx +39 -0
  28. package/client/ui/app-shell.stories.jsx +51 -0
  29. package/client/ui/aspect-ratio.jsx +6 -0
  30. package/client/ui/aspect-ratio.stories.jsx +69 -0
  31. package/client/ui/avatar.jsx +78 -0
  32. package/client/ui/avatar.stories.jsx +62 -0
  33. package/client/ui/badge.jsx +34 -0
  34. package/client/ui/badge.stories.js +32 -0
  35. package/client/ui/breadcrumb.jsx +86 -0
  36. package/client/ui/breadcrumb.stories.jsx +43 -0
  37. package/client/ui/button-group.jsx +58 -0
  38. package/client/ui/button-group.stories.jsx +67 -0
  39. package/client/ui/button.jsx +46 -0
  40. package/client/ui/button.stories.js +72 -0
  41. package/client/ui/calendar.jsx +172 -0
  42. package/client/ui/card.jsx +57 -0
  43. package/client/ui/card.stories.jsx +33 -0
  44. package/client/ui/carousel.jsx +167 -0
  45. package/client/ui/chart.jsx +244 -0
  46. package/client/ui/checkbox.jsx +24 -0
  47. package/client/ui/checkbox.stories.js +33 -0
  48. package/client/ui/collapsible.jsx +12 -0
  49. package/client/ui/collapsible.stories.jsx +42 -0
  50. package/client/ui/combobox.jsx +223 -0
  51. package/client/ui/command.jsx +128 -0
  52. package/client/ui/context-menu.jsx +170 -0
  53. package/client/ui/context-menu.stories.jsx +35 -0
  54. package/client/ui/dialog.jsx +109 -0
  55. package/client/ui/dialog.stories.jsx +37 -0
  56. package/client/ui/direction.jsx +9 -0
  57. package/client/ui/drawer.jsx +87 -0
  58. package/client/ui/dropdown-menu.jsx +172 -0
  59. package/client/ui/dropdown-menu.stories.jsx +34 -0
  60. package/client/ui/empty.jsx +76 -0
  61. package/client/ui/empty.stories.jsx +64 -0
  62. package/client/ui/field.jsx +174 -0
  63. package/client/ui/field.stories.jsx +118 -0
  64. package/client/ui/form.jsx +17 -0
  65. package/client/ui/hooks/use-mobile.js +16 -0
  66. package/client/ui/hover-card.jsx +26 -0
  67. package/client/ui/hover-card.stories.jsx +28 -0
  68. package/client/ui/index.js +649 -0
  69. package/client/ui/input-group.jsx +116 -0
  70. package/client/ui/input-group.stories.jsx +65 -0
  71. package/client/ui/input-otp.jsx +62 -0
  72. package/client/ui/input.jsx +16 -0
  73. package/client/ui/input.stories.js +27 -0
  74. package/client/ui/item.jsx +155 -0
  75. package/client/ui/item.stories.jsx +118 -0
  76. package/client/ui/kbd.jsx +24 -0
  77. package/client/ui/kbd.stories.jsx +32 -0
  78. package/client/ui/label.jsx +16 -0
  79. package/client/ui/label.stories.js +25 -0
  80. package/client/ui/lib/utils.js +6 -0
  81. package/client/ui/main-content.jsx +30 -0
  82. package/client/ui/menubar.jsx +189 -0
  83. package/client/ui/menubar.stories.jsx +43 -0
  84. package/client/ui/native-select.jsx +34 -0
  85. package/client/ui/native-select.stories.jsx +67 -0
  86. package/client/ui/navigation-menu.jsx +120 -0
  87. package/client/ui/navigation-menu.stories.jsx +45 -0
  88. package/client/ui/pagination.jsx +92 -0
  89. package/client/ui/pagination.stories.jsx +52 -0
  90. package/client/ui/panel.jsx +66 -0
  91. package/client/ui/popover.jsx +54 -0
  92. package/client/ui/popover.stories.jsx +27 -0
  93. package/client/ui/progress.jsx +19 -0
  94. package/client/ui/progress.stories.js +34 -0
  95. package/client/ui/radio-group.jsx +33 -0
  96. package/client/ui/radio-group.stories.jsx +49 -0
  97. package/client/ui/resizable.jsx +33 -0
  98. package/client/ui/scroll-area.jsx +41 -0
  99. package/client/ui/scroll-area.stories.jsx +43 -0
  100. package/client/ui/select.jsx +145 -0
  101. package/client/ui/select.stories.jsx +80 -0
  102. package/client/ui/separator.jsx +18 -0
  103. package/client/ui/separator.stories.jsx +37 -0
  104. package/client/ui/sheet.jsx +95 -0
  105. package/client/ui/sheet.stories.jsx +56 -0
  106. package/client/ui/sidebar.jsx +544 -0
  107. package/client/ui/skeleton.jsx +8 -0
  108. package/client/ui/skeleton.stories.js +23 -0
  109. package/client/ui/slider.jsx +41 -0
  110. package/client/ui/slider.stories.js +31 -0
  111. package/client/ui/sonner.jsx +37 -0
  112. package/client/ui/spinner.jsx +14 -0
  113. package/client/ui/spinner.stories.js +16 -0
  114. package/client/ui/style-mira.css +1316 -0
  115. package/client/ui/switch.jsx +22 -0
  116. package/client/ui/switch.stories.js +44 -0
  117. package/client/ui/table.jsx +33 -0
  118. package/client/ui/table.stories.jsx +42 -0
  119. package/client/ui/tabs.jsx +63 -0
  120. package/client/ui/tabs.stories.jsx +45 -0
  121. package/client/ui/textarea.jsx +15 -0
  122. package/client/ui/textarea.stories.js +33 -0
  123. package/client/ui/theme.css +459 -0
  124. package/client/ui/toggle-group.jsx +62 -0
  125. package/client/ui/toggle-group.stories.jsx +68 -0
  126. package/client/ui/toggle.jsx +34 -0
  127. package/client/ui/toggle.stories.js +46 -0
  128. package/client/ui/tooltip.jsx +37 -0
  129. package/client/ui/tooltip.stories.jsx +32 -0
  130. package/client/ui/use-transition.js +35 -0
  131. package/client/ws.js +132 -0
  132. package/package.json +134 -0
  133. package/server/bin/cli.js +42 -0
  134. package/server/bin/commands/build.js +23 -0
  135. package/server/bin/commands/dev.js +57 -0
  136. package/server/bin/commands/docs.js +30 -0
  137. package/server/bin/commands/graphql-schema.js +32 -0
  138. package/server/bin/commands/lint.js +35 -0
  139. package/server/bin/commands/mcp.js +26 -0
  140. package/server/bin/commands/migrate.js +82 -0
  141. package/server/bin/commands/schema.js +41 -0
  142. package/server/bin/commands/seed.js +36 -0
  143. package/server/bin/commands/start.js +31 -0
  144. package/server/bin/commands/test.js +20 -0
  145. package/server/bin/solo.js +4 -0
  146. package/server/boot/index.js +150 -0
  147. package/server/boot.js +2 -0
  148. package/server/build.js +23 -0
  149. package/server/cache/drivers/memory.js +23 -0
  150. package/server/cache/drivers/redis.js +28 -0
  151. package/server/cache/index.js +69 -0
  152. package/server/config/loader.js +89 -0
  153. package/server/config/modules/api.js +17 -0
  154. package/server/config/modules/build.js +9 -0
  155. package/server/config/modules/cache.js +10 -0
  156. package/server/config/modules/database.js +29 -0
  157. package/server/config/modules/events.js +15 -0
  158. package/server/config/modules/files.js +15 -0
  159. package/server/config/modules/jobs.js +20 -0
  160. package/server/config/modules/logger.js +9 -0
  161. package/server/config/modules/mail.js +11 -0
  162. package/server/config/modules/mcp.js +9 -0
  163. package/server/config/modules/pages.js +20 -0
  164. package/server/config/modules/queue.js +10 -0
  165. package/server/config/modules/redis.js +9 -0
  166. package/server/config/modules/server.js +30 -0
  167. package/server/config/modules/session.js +9 -0
  168. package/server/config/modules/websocket.js +11 -0
  169. package/server/constants.js +67 -0
  170. package/server/context.js +15 -0
  171. package/server/db/index.js +87 -0
  172. package/server/db/schema/drivers/mysql.js +28 -0
  173. package/server/db/schema/drivers/pg.js +34 -0
  174. package/server/db/schema/drivers/sqlite.js +22 -0
  175. package/server/db/schema/index.js +78 -0
  176. package/server/db/seeds.js +22 -0
  177. package/server/discovery.js +67 -0
  178. package/server/docs/openapi.js +153 -0
  179. package/server/env.js +17 -0
  180. package/server/events/drivers/memory.js +45 -0
  181. package/server/events/drivers/redis.js +64 -0
  182. package/server/events/handler.js +67 -0
  183. package/server/events/index.js +35 -0
  184. package/server/events/pattern.js +5 -0
  185. package/server/files/drivers/local.js +83 -0
  186. package/server/files/drivers/s3.js +113 -0
  187. package/server/files/index.js +57 -0
  188. package/server/filewatcher/index.js +156 -0
  189. package/server/glob.js +6 -0
  190. package/server/graphql/discovery.js +70 -0
  191. package/server/graphql/handler.js +41 -0
  192. package/server/graphql/index.js +13 -0
  193. package/server/graphql/loaders.js +19 -0
  194. package/server/graphql/merge.js +48 -0
  195. package/server/graphql/subscriptions.js +43 -0
  196. package/server/health.js +34 -0
  197. package/server/helpers.js +9 -0
  198. package/server/index.js +55 -0
  199. package/server/internals.js +139 -0
  200. package/server/jobs/cron.js +10 -0
  201. package/server/jobs/drivers/knex-queue.js +207 -0
  202. package/server/jobs/drivers/lease.js +148 -0
  203. package/server/jobs/drivers/memory-queue.js +134 -0
  204. package/server/jobs/queue.js +27 -0
  205. package/server/jobs/runner.js +197 -0
  206. package/server/jobs/throughput.js +63 -0
  207. package/server/lib/vault/encrypt.js +40 -0
  208. package/server/lib/vault/ids.js +9 -0
  209. package/server/lib/vault/index.js +14 -0
  210. package/server/lib/vault/jwt.js +55 -0
  211. package/server/lib/vault/password.js +10 -0
  212. package/server/lint/boundaries.js +77 -0
  213. package/server/logger/index.js +130 -0
  214. package/server/mail/drivers/console.js +31 -0
  215. package/server/mail/drivers/smtp.js +34 -0
  216. package/server/mail/imap.js +105 -0
  217. package/server/mail/inbound-store.js +58 -0
  218. package/server/mail/inbound.js +79 -0
  219. package/server/mail/index.js +112 -0
  220. package/server/mcp/debug-api.js +137 -0
  221. package/server/mcp/helpers.js +30 -0
  222. package/server/mcp/index.js +77 -0
  223. package/server/mcp/runtime.js +7 -0
  224. package/server/mcp/server.js +19 -0
  225. package/server/mcp/tools/debugging.js +133 -0
  226. package/server/mcp/tools/introspection.js +87 -0
  227. package/server/middlewares/cors.js +30 -0
  228. package/server/middlewares/index.js +3 -0
  229. package/server/middlewares/require-session.js +15 -0
  230. package/server/module-loader.js +9 -0
  231. package/server/pages/build-client.js +187 -0
  232. package/server/pages/build-css.js +47 -0
  233. package/server/pages/build-manifest.js +55 -0
  234. package/server/pages/build-plugins.js +75 -0
  235. package/server/pages/build-server.js +115 -0
  236. package/server/pages/build.js +116 -0
  237. package/server/pages/discovery.js +120 -0
  238. package/server/pages/fonts.js +128 -0
  239. package/server/pages/handler.js +276 -0
  240. package/server/pages/hmr.js +176 -0
  241. package/server/pages/pages-router.js +78 -0
  242. package/server/pages/ssr.js +276 -0
  243. package/server/pages/static.js +92 -0
  244. package/server/pages/watcher.js +90 -0
  245. package/server/queue/drivers/knex.js +67 -0
  246. package/server/queue/drivers/redis.js +91 -0
  247. package/server/queue/index.js +61 -0
  248. package/server/rate-limit/consume.js +21 -0
  249. package/server/rate-limit/drivers/memory.js +24 -0
  250. package/server/rate-limit/drivers/redis.js +32 -0
  251. package/server/rate-limit/index.js +33 -0
  252. package/server/redis/index.js +67 -0
  253. package/server/ring-buffer.js +44 -0
  254. package/server/route.js +4 -0
  255. package/server/router/api-router.js +317 -0
  256. package/server/router/cors.js +31 -0
  257. package/server/router/middleware.js +91 -0
  258. package/server/router/routes.js +132 -0
  259. package/server/server.js +35 -0
  260. package/server/session/helpers.js +21 -0
  261. package/server/session/index.js +89 -0
  262. package/server/static/index.js +36 -0
  263. package/server/system-jobs/index.js +50 -0
  264. package/server/system-routes/index.js +84 -0
  265. package/server/testing/index.js +263 -0
  266. package/server/validation.js +41 -0
  267. package/server/watcher.js +34 -0
  268. package/server/web-server.js +231 -0
  269. package/server/ws/discovery.js +54 -0
  270. package/server/ws/index.js +14 -0
  271. package/server/ws/realtime.js +318 -0
  272. package/server/ws/registry.js +17 -0
  273. package/server/ws/server.js +152 -0
  274. package/server/ws/ws-router.js +335 -0
@@ -0,0 +1,167 @@
1
+ import * as React from 'react';
2
+ import useEmblaCarousel from 'embla-carousel-react';
3
+ import { cn } from './lib/utils.js';
4
+ import { Button } from './button.jsx';
5
+ import { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';
6
+ const CarouselContext = React.createContext(null);
7
+ function useCarousel() {
8
+ const context = React.useContext(CarouselContext);
9
+ if (!context) {
10
+ throw new Error('useCarousel must be used within a <Carousel />');
11
+ }
12
+ return context;
13
+ }
14
+ function Carousel({
15
+ orientation = 'horizontal',
16
+ opts,
17
+ setApi,
18
+ plugins,
19
+ className,
20
+ children,
21
+ ...props
22
+ }) {
23
+ const [carouselRef, api] = useEmblaCarousel(
24
+ {
25
+ ...opts,
26
+ axis: orientation === 'horizontal' ? 'x' : 'y',
27
+ },
28
+ plugins,
29
+ );
30
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false);
31
+ const [canScrollNext, setCanScrollNext] = React.useState(false);
32
+ const onSelect = React.useCallback((api2) => {
33
+ if (!api2) return;
34
+ setCanScrollPrev(api2.canScrollPrev());
35
+ setCanScrollNext(api2.canScrollNext());
36
+ }, []);
37
+ const scrollPrev = React.useCallback(() => {
38
+ api?.scrollPrev();
39
+ }, [api]);
40
+ const scrollNext = React.useCallback(() => {
41
+ api?.scrollNext();
42
+ }, [api]);
43
+ const handleKeyDown = React.useCallback(
44
+ (event) => {
45
+ if (event.key === 'ArrowLeft') {
46
+ event.preventDefault();
47
+ scrollPrev();
48
+ } else if (event.key === 'ArrowRight') {
49
+ event.preventDefault();
50
+ scrollNext();
51
+ }
52
+ },
53
+ [scrollPrev, scrollNext],
54
+ );
55
+ React.useEffect(() => {
56
+ if (!api || !setApi) return;
57
+ setApi(api);
58
+ }, [api, setApi]);
59
+ React.useEffect(() => {
60
+ if (!api) return;
61
+ onSelect(api);
62
+ api.on('reInit', onSelect);
63
+ api.on('select', onSelect);
64
+ return () => {
65
+ api?.off('select', onSelect);
66
+ };
67
+ }, [api, onSelect]);
68
+ return (
69
+ <CarouselContext.Provider
70
+ value={{
71
+ carouselRef,
72
+ api,
73
+ opts,
74
+ orientation: orientation || (opts?.axis === 'y' ? 'vertical' : 'horizontal'),
75
+ scrollPrev,
76
+ scrollNext,
77
+ canScrollPrev,
78
+ canScrollNext,
79
+ }}
80
+ >
81
+ <div
82
+ onKeyDownCapture={handleKeyDown}
83
+ className={cn('relative', className)}
84
+ role="region"
85
+ aria-roledescription="carousel"
86
+ data-slot="carousel"
87
+ {...props}
88
+ >
89
+ {children}
90
+ </div>
91
+ </CarouselContext.Provider>
92
+ );
93
+ }
94
+ function CarouselContent({ className, ...props }) {
95
+ const { carouselRef, orientation } = useCarousel();
96
+ return (
97
+ <div ref={carouselRef} className="overflow-hidden" data-slot="carousel-content">
98
+ <div
99
+ className={cn('flex', orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col', className)}
100
+ {...props}
101
+ />
102
+ </div>
103
+ );
104
+ }
105
+ function CarouselItem({ className, ...props }) {
106
+ const { orientation } = useCarousel();
107
+ return (
108
+ <div
109
+ role="group"
110
+ aria-roledescription="slide"
111
+ data-slot="carousel-item"
112
+ className={cn(
113
+ 'min-w-0 shrink-0 grow-0 basis-full',
114
+ orientation === 'horizontal' ? 'pl-4' : 'pt-4',
115
+ className,
116
+ )}
117
+ {...props}
118
+ />
119
+ );
120
+ }
121
+ function CarouselPrevious({ className, variant = 'outline', size = 'icon-sm', ...props }) {
122
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel();
123
+ return (
124
+ <Button
125
+ data-slot="carousel-previous"
126
+ variant={variant}
127
+ size={size}
128
+ className={cn(
129
+ 'cn-carousel-previous absolute touch-manipulation',
130
+ orientation === 'horizontal'
131
+ ? 'top-1/2 -left-12 -translate-y-1/2'
132
+ : '-top-12 left-1/2 -translate-x-1/2 rotate-90',
133
+ className,
134
+ )}
135
+ disabled={!canScrollPrev}
136
+ onClick={scrollPrev}
137
+ {...props}
138
+ >
139
+ <ChevronLeftIcon className="cn-rtl-flip" />
140
+ <span className="sr-only">Previous slide</span>
141
+ </Button>
142
+ );
143
+ }
144
+ function CarouselNext({ className, variant = 'outline', size = 'icon-sm', ...props }) {
145
+ const { orientation, scrollNext, canScrollNext } = useCarousel();
146
+ return (
147
+ <Button
148
+ data-slot="carousel-next"
149
+ variant={variant}
150
+ size={size}
151
+ className={cn(
152
+ 'cn-carousel-next absolute touch-manipulation',
153
+ orientation === 'horizontal'
154
+ ? 'top-1/2 -right-12 -translate-y-1/2'
155
+ : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
156
+ className,
157
+ )}
158
+ disabled={!canScrollNext}
159
+ onClick={scrollNext}
160
+ {...props}
161
+ >
162
+ <ChevronRightIcon className="cn-rtl-flip" />
163
+ <span className="sr-only">Next slide</span>
164
+ </Button>
165
+ );
166
+ }
167
+ export { Carousel, CarouselContent, CarouselItem, CarouselNext, CarouselPrevious, useCarousel };
@@ -0,0 +1,244 @@
1
+ import * as React from 'react';
2
+ import * as RechartsPrimitive from 'recharts';
3
+ import { cn } from './lib/utils.js';
4
+ const THEMES = { light: '', dark: '.dark' };
5
+ const ChartContext = React.createContext(null);
6
+ function useChart() {
7
+ const context = React.useContext(ChartContext);
8
+ if (!context) {
9
+ throw new Error('useChart must be used within a <ChartContainer />');
10
+ }
11
+ return context;
12
+ }
13
+ function ChartContainer({ id, className, children, config, ...props }) {
14
+ const uniqueId = React.useId();
15
+ const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`;
16
+ return (
17
+ <ChartContext.Provider value={{ config }}>
18
+ <div
19
+ data-slot="chart"
20
+ data-chart={chartId}
21
+ className={cn(
22
+ "cn-chart [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
23
+ className,
24
+ )}
25
+ {...props}
26
+ >
27
+ <ChartStyle id={chartId} config={config} />
28
+ <RechartsPrimitive.ResponsiveContainer>{children}</RechartsPrimitive.ResponsiveContainer>
29
+ </div>
30
+ </ChartContext.Provider>
31
+ );
32
+ }
33
+ const ChartStyle = ({ id, config }) => {
34
+ const colorConfig = Object.entries(config).filter(
35
+ ([, config2]) => config2.theme || config2.color,
36
+ );
37
+ if (!colorConfig.length) {
38
+ return null;
39
+ }
40
+ return (
41
+ <style
42
+ dangerouslySetInnerHTML={{
43
+ __html: Object.entries(THEMES)
44
+ .map(
45
+ ([theme, prefix]) => `
46
+ ${prefix} [data-chart=${id}] {
47
+ ${colorConfig
48
+ .map(([key, itemConfig]) => {
49
+ const color = itemConfig.theme?.[theme] || itemConfig.color;
50
+ return color ? ` --color-${key}: ${color};` : null;
51
+ })
52
+ .join('\n')}
53
+ }
54
+ `,
55
+ )
56
+ .join('\n'),
57
+ }}
58
+ />
59
+ );
60
+ };
61
+ const ChartTooltip = RechartsPrimitive.Tooltip;
62
+ function ChartTooltipContent({
63
+ active,
64
+ payload,
65
+ className,
66
+ indicator = 'dot',
67
+ hideLabel = false,
68
+ hideIndicator = false,
69
+ label,
70
+ labelFormatter,
71
+ labelClassName,
72
+ formatter,
73
+ color,
74
+ nameKey,
75
+ labelKey,
76
+ }) {
77
+ const { config } = useChart();
78
+ const tooltipLabel = React.useMemo(() => {
79
+ if (hideLabel || !payload?.length) {
80
+ return null;
81
+ }
82
+ const [item] = payload;
83
+ const key = `${labelKey || item?.dataKey || item?.name || 'value'}`;
84
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
85
+ const value =
86
+ !labelKey && typeof label === 'string' ? config[label]?.label || label : itemConfig?.label;
87
+ if (labelFormatter) {
88
+ return (
89
+ <div className={cn('font-medium', labelClassName)}>{labelFormatter(value, payload)}</div>
90
+ );
91
+ }
92
+ if (!value) {
93
+ return null;
94
+ }
95
+ return <div className={cn('font-medium', labelClassName)}>{value}</div>;
96
+ }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);
97
+ if (!active || !payload?.length) {
98
+ return null;
99
+ }
100
+ const nestLabel = payload.length === 1 && indicator !== 'dot';
101
+ return (
102
+ <div className={cn('cn-chart-tooltip grid min-w-32 items-start', className)}>
103
+ {!nestLabel ? tooltipLabel : null}
104
+ <div className="grid gap-1.5">
105
+ {payload
106
+ .filter((item) => item.type !== 'none')
107
+ .map((item, index) => {
108
+ const key = `${nameKey || item.name || item.dataKey || 'value'}`;
109
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
110
+ const indicatorColor = color || item.payload.fill || item.color;
111
+ return (
112
+ <div
113
+ key={item.dataKey}
114
+ className={cn(
115
+ '[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5',
116
+ indicator === 'dot' && 'items-center',
117
+ )}
118
+ >
119
+ {formatter && item?.value !== void 0 && item.name ? (
120
+ formatter(item.value, item.name, item, index, item.payload)
121
+ ) : (
122
+ <>
123
+ {itemConfig?.icon ? (
124
+ <itemConfig.icon />
125
+ ) : (
126
+ !hideIndicator && (
127
+ <div
128
+ className={cn(
129
+ 'shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)',
130
+ {
131
+ 'h-2.5 w-2.5': indicator === 'dot',
132
+ 'w-1': indicator === 'line',
133
+ 'w-0 border-[1.5px] border-dashed bg-transparent':
134
+ indicator === 'dashed',
135
+ 'my-0.5': nestLabel && indicator === 'dashed',
136
+ },
137
+ )}
138
+ style={{
139
+ '--color-bg': indicatorColor,
140
+ '--color-border': indicatorColor,
141
+ }}
142
+ />
143
+ )
144
+ )}
145
+ <div
146
+ className={cn(
147
+ 'flex flex-1 justify-between leading-none',
148
+ nestLabel ? 'items-end' : 'items-center',
149
+ )}
150
+ >
151
+ <div className="grid gap-1.5">
152
+ {nestLabel ? tooltipLabel : null}
153
+ <span className="text-muted-foreground">
154
+ {itemConfig?.label || item.name}
155
+ </span>
156
+ </div>
157
+ {item.value && (
158
+ <span className="text-foreground font-mono font-medium tabular-nums">
159
+ {item.value.toLocaleString()}
160
+ </span>
161
+ )}
162
+ </div>
163
+ </>
164
+ )}
165
+ </div>
166
+ );
167
+ })}
168
+ </div>
169
+ </div>
170
+ );
171
+ }
172
+ const ChartLegend = RechartsPrimitive.Legend;
173
+ function ChartLegendContent({
174
+ className,
175
+ hideIcon = false,
176
+ payload,
177
+ verticalAlign = 'bottom',
178
+ nameKey,
179
+ }) {
180
+ const { config } = useChart();
181
+ if (!payload?.length) {
182
+ return null;
183
+ }
184
+ return (
185
+ <div
186
+ className={cn(
187
+ 'flex items-center justify-center gap-4',
188
+ verticalAlign === 'top' ? 'pb-3' : 'pt-3',
189
+ className,
190
+ )}
191
+ >
192
+ {payload
193
+ .filter((item) => item.type !== 'none')
194
+ .map((item) => {
195
+ const key = `${nameKey || item.dataKey || 'value'}`;
196
+ const itemConfig = getPayloadConfigFromPayload(config, item, key);
197
+ return (
198
+ <div
199
+ key={item.value}
200
+ className={cn(
201
+ '[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3',
202
+ )}
203
+ >
204
+ {itemConfig?.icon && !hideIcon ? (
205
+ <itemConfig.icon />
206
+ ) : (
207
+ <div
208
+ className="h-2 w-2 shrink-0 rounded-[2px]"
209
+ style={{
210
+ backgroundColor: item.color,
211
+ }}
212
+ />
213
+ )}
214
+ {itemConfig?.label}
215
+ </div>
216
+ );
217
+ })}
218
+ </div>
219
+ );
220
+ }
221
+ function getPayloadConfigFromPayload(config, payload, key) {
222
+ if (typeof payload !== 'object' || payload === null) {
223
+ return void 0;
224
+ }
225
+ const payloadPayload =
226
+ 'payload' in payload && typeof payload.payload === 'object' && payload.payload !== null
227
+ ? payload.payload
228
+ : void 0;
229
+ let configLabelKey = key;
230
+ if (key in payload && typeof payload[key] === 'string') {
231
+ configLabelKey = payload[key];
232
+ } else if (payloadPayload && key in payloadPayload && typeof payloadPayload[key] === 'string') {
233
+ configLabelKey = payloadPayload[key];
234
+ }
235
+ return configLabelKey in config ? config[configLabelKey] : config[key];
236
+ }
237
+ export {
238
+ ChartContainer,
239
+ ChartLegend,
240
+ ChartLegendContent,
241
+ ChartStyle,
242
+ ChartTooltip,
243
+ ChartTooltipContent,
244
+ };
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { Checkbox as CheckboxPrimitive } from 'radix-ui';
3
+ import { cn } from './lib/utils.js';
4
+ import { CheckIcon } from 'lucide-react';
5
+ function Checkbox({ className, ...props }) {
6
+ return (
7
+ <CheckboxPrimitive.Root
8
+ data-slot="checkbox"
9
+ className={cn(
10
+ 'cn-checkbox peer relative shrink-0 outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50',
11
+ className,
12
+ )}
13
+ {...props}
14
+ >
15
+ <CheckboxPrimitive.Indicator
16
+ data-slot="checkbox-indicator"
17
+ className="cn-checkbox-indicator grid place-content-center text-current transition-none"
18
+ >
19
+ <CheckIcon />
20
+ </CheckboxPrimitive.Indicator>
21
+ </CheckboxPrimitive.Root>
22
+ );
23
+ }
24
+ export { Checkbox };
@@ -0,0 +1,33 @@
1
+ import { expect, within } from 'storybook/test';
2
+ import { Checkbox } from './checkbox.jsx';
3
+ const meta = {
4
+ title: 'UI/Checkbox',
5
+ component: Checkbox,
6
+ };
7
+ var stdin_default = meta;
8
+ const Default = {
9
+ play: async ({ canvasElement }) => {
10
+ const canvas = within(canvasElement);
11
+ const cb = canvas.getByRole('checkbox');
12
+ await expect(cb).toBeInTheDocument();
13
+ await expect(cb.dataset.slot).toBe('checkbox');
14
+ await expect(cb.dataset.state).toBe('unchecked');
15
+ },
16
+ };
17
+ const Checked = {
18
+ args: { defaultChecked: true },
19
+ play: async ({ canvasElement }) => {
20
+ const canvas = within(canvasElement);
21
+ const cb = canvas.getByRole('checkbox');
22
+ await expect(cb.dataset.state).toBe('checked');
23
+ },
24
+ };
25
+ const Disabled = {
26
+ args: { disabled: true },
27
+ play: async ({ canvasElement }) => {
28
+ const canvas = within(canvasElement);
29
+ const cb = canvas.getByRole('checkbox');
30
+ await expect(cb).toBeDisabled();
31
+ },
32
+ };
33
+ export { Checked, Default, Disabled, stdin_default as default };
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { Collapsible as CollapsiblePrimitive } from 'radix-ui';
3
+ function Collapsible({ ...props }) {
4
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
5
+ }
6
+ function CollapsibleTrigger({ ...props }) {
7
+ return <CollapsiblePrimitive.CollapsibleTrigger data-slot="collapsible-trigger" {...props} />;
8
+ }
9
+ function CollapsibleContent({ ...props }) {
10
+ return <CollapsiblePrimitive.CollapsibleContent data-slot="collapsible-content" {...props} />;
11
+ }
12
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger };
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { expect, within } from 'storybook/test';
3
+ import { Collapsible, CollapsibleTrigger, CollapsibleContent } from './collapsible.jsx';
4
+ const meta = {
5
+ title: 'UI/Collapsible',
6
+ component: Collapsible,
7
+ };
8
+ var stdin_default = meta;
9
+ const Default = {
10
+ render: () => (
11
+ <Collapsible>
12
+ <CollapsibleTrigger asChild>
13
+ <button>Toggle</button>
14
+ </CollapsibleTrigger>
15
+ <CollapsibleContent>
16
+ <p>Collapsible content here.</p>
17
+ </CollapsibleContent>
18
+ </Collapsible>
19
+ ),
20
+ play: async ({ canvasElement }) => {
21
+ const canvas = within(canvasElement);
22
+ const trigger = canvas.getByRole('button', { name: 'Toggle' });
23
+ await expect(trigger).toBeInTheDocument();
24
+ },
25
+ };
26
+ const DefaultOpen = {
27
+ render: () => (
28
+ <Collapsible defaultOpen>
29
+ <CollapsibleTrigger asChild>
30
+ <button>Toggle</button>
31
+ </CollapsibleTrigger>
32
+ <CollapsibleContent>
33
+ <p>Visible by default.</p>
34
+ </CollapsibleContent>
35
+ </Collapsible>
36
+ ),
37
+ play: async ({ canvasElement }) => {
38
+ const canvas = within(canvasElement);
39
+ await expect(canvas.getByText('Visible by default.')).toBeInTheDocument();
40
+ },
41
+ };
42
+ export { Default, DefaultOpen, stdin_default as default };