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.
- package/LICENSE +21 -0
- package/README.md +711 -0
- package/client/env.js +55 -0
- package/client/fetcher.js +50 -0
- package/client/graphql.js +35 -0
- package/client/head.js +140 -0
- package/client/hooks/use-api.js +80 -0
- package/client/hooks/use-debounce.js +12 -0
- package/client/hooks/use-form.js +86 -0
- package/client/hooks/use-graphql.js +30 -0
- package/client/hooks/use-interval.js +12 -0
- package/client/hooks/use-mutation.js +27 -0
- package/client/hooks/use-query.js +45 -0
- package/client/hooks/web/use-click-outside.js +22 -0
- package/client/hooks/web/use-local-storage.js +42 -0
- package/client/index.js +62 -0
- package/client/page-loader.js +155 -0
- package/client/provider.js +53 -0
- package/client/query.js +13 -0
- package/client/router.jsx +303 -0
- package/client/ui/accordion.jsx +65 -0
- package/client/ui/accordion.stories.jsx +48 -0
- package/client/ui/alert-dialog.jsx +122 -0
- package/client/ui/alert-dialog.stories.jsx +44 -0
- package/client/ui/alert.jsx +52 -0
- package/client/ui/alert.stories.jsx +31 -0
- package/client/ui/app-shell.jsx +39 -0
- package/client/ui/app-shell.stories.jsx +51 -0
- package/client/ui/aspect-ratio.jsx +6 -0
- package/client/ui/aspect-ratio.stories.jsx +69 -0
- package/client/ui/avatar.jsx +78 -0
- package/client/ui/avatar.stories.jsx +62 -0
- package/client/ui/badge.jsx +34 -0
- package/client/ui/badge.stories.js +32 -0
- package/client/ui/breadcrumb.jsx +86 -0
- package/client/ui/breadcrumb.stories.jsx +43 -0
- package/client/ui/button-group.jsx +58 -0
- package/client/ui/button-group.stories.jsx +67 -0
- package/client/ui/button.jsx +46 -0
- package/client/ui/button.stories.js +72 -0
- package/client/ui/calendar.jsx +172 -0
- package/client/ui/card.jsx +57 -0
- package/client/ui/card.stories.jsx +33 -0
- package/client/ui/carousel.jsx +167 -0
- package/client/ui/chart.jsx +244 -0
- package/client/ui/checkbox.jsx +24 -0
- package/client/ui/checkbox.stories.js +33 -0
- package/client/ui/collapsible.jsx +12 -0
- package/client/ui/collapsible.stories.jsx +42 -0
- package/client/ui/combobox.jsx +223 -0
- package/client/ui/command.jsx +128 -0
- package/client/ui/context-menu.jsx +170 -0
- package/client/ui/context-menu.stories.jsx +35 -0
- package/client/ui/dialog.jsx +109 -0
- package/client/ui/dialog.stories.jsx +37 -0
- package/client/ui/direction.jsx +9 -0
- package/client/ui/drawer.jsx +87 -0
- package/client/ui/dropdown-menu.jsx +172 -0
- package/client/ui/dropdown-menu.stories.jsx +34 -0
- package/client/ui/empty.jsx +76 -0
- package/client/ui/empty.stories.jsx +64 -0
- package/client/ui/field.jsx +174 -0
- package/client/ui/field.stories.jsx +118 -0
- package/client/ui/form.jsx +17 -0
- package/client/ui/hooks/use-mobile.js +16 -0
- package/client/ui/hover-card.jsx +26 -0
- package/client/ui/hover-card.stories.jsx +28 -0
- package/client/ui/index.js +649 -0
- package/client/ui/input-group.jsx +116 -0
- package/client/ui/input-group.stories.jsx +65 -0
- package/client/ui/input-otp.jsx +62 -0
- package/client/ui/input.jsx +16 -0
- package/client/ui/input.stories.js +27 -0
- package/client/ui/item.jsx +155 -0
- package/client/ui/item.stories.jsx +118 -0
- package/client/ui/kbd.jsx +24 -0
- package/client/ui/kbd.stories.jsx +32 -0
- package/client/ui/label.jsx +16 -0
- package/client/ui/label.stories.js +25 -0
- package/client/ui/lib/utils.js +6 -0
- package/client/ui/main-content.jsx +30 -0
- package/client/ui/menubar.jsx +189 -0
- package/client/ui/menubar.stories.jsx +43 -0
- package/client/ui/native-select.jsx +34 -0
- package/client/ui/native-select.stories.jsx +67 -0
- package/client/ui/navigation-menu.jsx +120 -0
- package/client/ui/navigation-menu.stories.jsx +45 -0
- package/client/ui/pagination.jsx +92 -0
- package/client/ui/pagination.stories.jsx +52 -0
- package/client/ui/panel.jsx +66 -0
- package/client/ui/popover.jsx +54 -0
- package/client/ui/popover.stories.jsx +27 -0
- package/client/ui/progress.jsx +19 -0
- package/client/ui/progress.stories.js +34 -0
- package/client/ui/radio-group.jsx +33 -0
- package/client/ui/radio-group.stories.jsx +49 -0
- package/client/ui/resizable.jsx +33 -0
- package/client/ui/scroll-area.jsx +41 -0
- package/client/ui/scroll-area.stories.jsx +43 -0
- package/client/ui/select.jsx +145 -0
- package/client/ui/select.stories.jsx +80 -0
- package/client/ui/separator.jsx +18 -0
- package/client/ui/separator.stories.jsx +37 -0
- package/client/ui/sheet.jsx +95 -0
- package/client/ui/sheet.stories.jsx +56 -0
- package/client/ui/sidebar.jsx +544 -0
- package/client/ui/skeleton.jsx +8 -0
- package/client/ui/skeleton.stories.js +23 -0
- package/client/ui/slider.jsx +41 -0
- package/client/ui/slider.stories.js +31 -0
- package/client/ui/sonner.jsx +37 -0
- package/client/ui/spinner.jsx +14 -0
- package/client/ui/spinner.stories.js +16 -0
- package/client/ui/style-mira.css +1316 -0
- package/client/ui/switch.jsx +22 -0
- package/client/ui/switch.stories.js +44 -0
- package/client/ui/table.jsx +33 -0
- package/client/ui/table.stories.jsx +42 -0
- package/client/ui/tabs.jsx +63 -0
- package/client/ui/tabs.stories.jsx +45 -0
- package/client/ui/textarea.jsx +15 -0
- package/client/ui/textarea.stories.js +33 -0
- package/client/ui/theme.css +459 -0
- package/client/ui/toggle-group.jsx +62 -0
- package/client/ui/toggle-group.stories.jsx +68 -0
- package/client/ui/toggle.jsx +34 -0
- package/client/ui/toggle.stories.js +46 -0
- package/client/ui/tooltip.jsx +37 -0
- package/client/ui/tooltip.stories.jsx +32 -0
- package/client/ui/use-transition.js +35 -0
- package/client/ws.js +132 -0
- package/package.json +134 -0
- package/server/bin/cli.js +42 -0
- package/server/bin/commands/build.js +23 -0
- package/server/bin/commands/dev.js +57 -0
- package/server/bin/commands/docs.js +30 -0
- package/server/bin/commands/graphql-schema.js +32 -0
- package/server/bin/commands/lint.js +35 -0
- package/server/bin/commands/mcp.js +26 -0
- package/server/bin/commands/migrate.js +82 -0
- package/server/bin/commands/schema.js +41 -0
- package/server/bin/commands/seed.js +36 -0
- package/server/bin/commands/start.js +31 -0
- package/server/bin/commands/test.js +20 -0
- package/server/bin/solo.js +4 -0
- package/server/boot/index.js +150 -0
- package/server/boot.js +2 -0
- package/server/build.js +23 -0
- package/server/cache/drivers/memory.js +23 -0
- package/server/cache/drivers/redis.js +28 -0
- package/server/cache/index.js +69 -0
- package/server/config/loader.js +89 -0
- package/server/config/modules/api.js +17 -0
- package/server/config/modules/build.js +9 -0
- package/server/config/modules/cache.js +10 -0
- package/server/config/modules/database.js +29 -0
- package/server/config/modules/events.js +15 -0
- package/server/config/modules/files.js +15 -0
- package/server/config/modules/jobs.js +20 -0
- package/server/config/modules/logger.js +9 -0
- package/server/config/modules/mail.js +11 -0
- package/server/config/modules/mcp.js +9 -0
- package/server/config/modules/pages.js +20 -0
- package/server/config/modules/queue.js +10 -0
- package/server/config/modules/redis.js +9 -0
- package/server/config/modules/server.js +30 -0
- package/server/config/modules/session.js +9 -0
- package/server/config/modules/websocket.js +11 -0
- package/server/constants.js +67 -0
- package/server/context.js +15 -0
- package/server/db/index.js +87 -0
- package/server/db/schema/drivers/mysql.js +28 -0
- package/server/db/schema/drivers/pg.js +34 -0
- package/server/db/schema/drivers/sqlite.js +22 -0
- package/server/db/schema/index.js +78 -0
- package/server/db/seeds.js +22 -0
- package/server/discovery.js +67 -0
- package/server/docs/openapi.js +153 -0
- package/server/env.js +17 -0
- package/server/events/drivers/memory.js +45 -0
- package/server/events/drivers/redis.js +64 -0
- package/server/events/handler.js +67 -0
- package/server/events/index.js +35 -0
- package/server/events/pattern.js +5 -0
- package/server/files/drivers/local.js +83 -0
- package/server/files/drivers/s3.js +113 -0
- package/server/files/index.js +57 -0
- package/server/filewatcher/index.js +156 -0
- package/server/glob.js +6 -0
- package/server/graphql/discovery.js +70 -0
- package/server/graphql/handler.js +41 -0
- package/server/graphql/index.js +13 -0
- package/server/graphql/loaders.js +19 -0
- package/server/graphql/merge.js +48 -0
- package/server/graphql/subscriptions.js +43 -0
- package/server/health.js +34 -0
- package/server/helpers.js +9 -0
- package/server/index.js +55 -0
- package/server/internals.js +139 -0
- package/server/jobs/cron.js +10 -0
- package/server/jobs/drivers/knex-queue.js +207 -0
- package/server/jobs/drivers/lease.js +148 -0
- package/server/jobs/drivers/memory-queue.js +134 -0
- package/server/jobs/queue.js +27 -0
- package/server/jobs/runner.js +197 -0
- package/server/jobs/throughput.js +63 -0
- package/server/lib/vault/encrypt.js +40 -0
- package/server/lib/vault/ids.js +9 -0
- package/server/lib/vault/index.js +14 -0
- package/server/lib/vault/jwt.js +55 -0
- package/server/lib/vault/password.js +10 -0
- package/server/lint/boundaries.js +77 -0
- package/server/logger/index.js +130 -0
- package/server/mail/drivers/console.js +31 -0
- package/server/mail/drivers/smtp.js +34 -0
- package/server/mail/imap.js +105 -0
- package/server/mail/inbound-store.js +58 -0
- package/server/mail/inbound.js +79 -0
- package/server/mail/index.js +112 -0
- package/server/mcp/debug-api.js +137 -0
- package/server/mcp/helpers.js +30 -0
- package/server/mcp/index.js +77 -0
- package/server/mcp/runtime.js +7 -0
- package/server/mcp/server.js +19 -0
- package/server/mcp/tools/debugging.js +133 -0
- package/server/mcp/tools/introspection.js +87 -0
- package/server/middlewares/cors.js +30 -0
- package/server/middlewares/index.js +3 -0
- package/server/middlewares/require-session.js +15 -0
- package/server/module-loader.js +9 -0
- package/server/pages/build-client.js +187 -0
- package/server/pages/build-css.js +47 -0
- package/server/pages/build-manifest.js +55 -0
- package/server/pages/build-plugins.js +75 -0
- package/server/pages/build-server.js +115 -0
- package/server/pages/build.js +116 -0
- package/server/pages/discovery.js +120 -0
- package/server/pages/fonts.js +128 -0
- package/server/pages/handler.js +276 -0
- package/server/pages/hmr.js +176 -0
- package/server/pages/pages-router.js +78 -0
- package/server/pages/ssr.js +276 -0
- package/server/pages/static.js +92 -0
- package/server/pages/watcher.js +90 -0
- package/server/queue/drivers/knex.js +67 -0
- package/server/queue/drivers/redis.js +91 -0
- package/server/queue/index.js +61 -0
- package/server/rate-limit/consume.js +21 -0
- package/server/rate-limit/drivers/memory.js +24 -0
- package/server/rate-limit/drivers/redis.js +32 -0
- package/server/rate-limit/index.js +33 -0
- package/server/redis/index.js +67 -0
- package/server/ring-buffer.js +44 -0
- package/server/route.js +4 -0
- package/server/router/api-router.js +317 -0
- package/server/router/cors.js +31 -0
- package/server/router/middleware.js +91 -0
- package/server/router/routes.js +132 -0
- package/server/server.js +35 -0
- package/server/session/helpers.js +21 -0
- package/server/session/index.js +89 -0
- package/server/static/index.js +36 -0
- package/server/system-jobs/index.js +50 -0
- package/server/system-routes/index.js +84 -0
- package/server/testing/index.js +263 -0
- package/server/validation.js +41 -0
- package/server/watcher.js +34 -0
- package/server/web-server.js +231 -0
- package/server/ws/discovery.js +54 -0
- package/server/ws/index.js +14 -0
- package/server/ws/realtime.js +318 -0
- package/server/ws/registry.js +17 -0
- package/server/ws/server.js +152 -0
- package/server/ws/ws-router.js +335 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Direction } from 'radix-ui';
|
|
3
|
+
function DirectionProvider({ dir, direction, children }) {
|
|
4
|
+
return (
|
|
5
|
+
<Direction.DirectionProvider dir={direction ?? dir}>{children}</Direction.DirectionProvider>
|
|
6
|
+
);
|
|
7
|
+
}
|
|
8
|
+
const useDirection = Direction.useDirection;
|
|
9
|
+
export { DirectionProvider, useDirection };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Drawer as DrawerPrimitive } from 'vaul';
|
|
3
|
+
import { cn } from './lib/utils.js';
|
|
4
|
+
function Drawer({ ...props }) {
|
|
5
|
+
return <DrawerPrimitive.Root data-slot="drawer" {...props} />;
|
|
6
|
+
}
|
|
7
|
+
function DrawerTrigger({ ...props }) {
|
|
8
|
+
return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />;
|
|
9
|
+
}
|
|
10
|
+
function DrawerPortal({ ...props }) {
|
|
11
|
+
return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />;
|
|
12
|
+
}
|
|
13
|
+
function DrawerClose({ ...props }) {
|
|
14
|
+
return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />;
|
|
15
|
+
}
|
|
16
|
+
function DrawerOverlay({ className, ...props }) {
|
|
17
|
+
return (
|
|
18
|
+
<DrawerPrimitive.Overlay
|
|
19
|
+
data-slot="drawer-overlay"
|
|
20
|
+
className={cn('cn-drawer-overlay fixed inset-0 z-50', className)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
function DrawerContent({ className, children, ...props }) {
|
|
26
|
+
return (
|
|
27
|
+
<DrawerPortal data-slot="drawer-portal">
|
|
28
|
+
<DrawerOverlay />
|
|
29
|
+
<DrawerPrimitive.Content
|
|
30
|
+
data-slot="drawer-content"
|
|
31
|
+
className={cn('cn-drawer-content group/drawer-content fixed z-50', className)}
|
|
32
|
+
{...props}
|
|
33
|
+
>
|
|
34
|
+
<div className="cn-drawer-handle mx-auto hidden shrink-0 group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
|
|
35
|
+
{children}
|
|
36
|
+
</DrawerPrimitive.Content>
|
|
37
|
+
</DrawerPortal>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
function DrawerHeader({ className, ...props }) {
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
data-slot="drawer-header"
|
|
44
|
+
className={cn('cn-drawer-header flex flex-col', className)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
function DrawerFooter({ className, ...props }) {
|
|
50
|
+
return (
|
|
51
|
+
<div
|
|
52
|
+
data-slot="drawer-footer"
|
|
53
|
+
className={cn('cn-drawer-footer mt-auto flex flex-col', className)}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
function DrawerTitle({ className, ...props }) {
|
|
59
|
+
return (
|
|
60
|
+
<DrawerPrimitive.Title
|
|
61
|
+
data-slot="drawer-title"
|
|
62
|
+
className={cn('cn-drawer-title', className)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function DrawerDescription({ className, ...props }) {
|
|
68
|
+
return (
|
|
69
|
+
<DrawerPrimitive.Description
|
|
70
|
+
data-slot="drawer-description"
|
|
71
|
+
className={cn('cn-drawer-description', className)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
export {
|
|
77
|
+
Drawer,
|
|
78
|
+
DrawerClose,
|
|
79
|
+
DrawerContent,
|
|
80
|
+
DrawerDescription,
|
|
81
|
+
DrawerFooter,
|
|
82
|
+
DrawerHeader,
|
|
83
|
+
DrawerOverlay,
|
|
84
|
+
DrawerPortal,
|
|
85
|
+
DrawerTitle,
|
|
86
|
+
DrawerTrigger,
|
|
87
|
+
};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { DropdownMenu as DropdownMenuPrimitive } from 'radix-ui';
|
|
3
|
+
import { cn } from './lib/utils.js';
|
|
4
|
+
import { CheckIcon, ChevronRightIcon } from 'lucide-react';
|
|
5
|
+
function DropdownMenu({ ...props }) {
|
|
6
|
+
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
|
7
|
+
}
|
|
8
|
+
function DropdownMenuPortal({ ...props }) {
|
|
9
|
+
return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
function DropdownMenuTrigger({ ...props }) {
|
|
12
|
+
return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />;
|
|
13
|
+
}
|
|
14
|
+
function DropdownMenuContent({ className, align = 'start', sideOffset = 4, ...props }) {
|
|
15
|
+
return (
|
|
16
|
+
<DropdownMenuPrimitive.Portal>
|
|
17
|
+
<DropdownMenuPrimitive.Content
|
|
18
|
+
data-slot="dropdown-menu-content"
|
|
19
|
+
sideOffset={sideOffset}
|
|
20
|
+
align={align}
|
|
21
|
+
className={cn(
|
|
22
|
+
'cn-dropdown-menu-content cn-menu-target z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto data-[state=closed]:overflow-hidden',
|
|
23
|
+
className,
|
|
24
|
+
)}
|
|
25
|
+
{...props}
|
|
26
|
+
/>
|
|
27
|
+
</DropdownMenuPrimitive.Portal>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
function DropdownMenuGroup({ ...props }) {
|
|
31
|
+
return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
|
|
32
|
+
}
|
|
33
|
+
function DropdownMenuItem({ className, inset, variant = 'default', ...props }) {
|
|
34
|
+
return (
|
|
35
|
+
<DropdownMenuPrimitive.Item
|
|
36
|
+
data-slot="dropdown-menu-item"
|
|
37
|
+
data-inset={inset}
|
|
38
|
+
data-variant={variant}
|
|
39
|
+
className={cn(
|
|
40
|
+
'cn-dropdown-menu-item group/dropdown-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
|
41
|
+
className,
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function DropdownMenuCheckboxItem({ className, children, checked, inset, ...props }) {
|
|
48
|
+
return (
|
|
49
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
50
|
+
data-slot="dropdown-menu-checkbox-item"
|
|
51
|
+
data-inset={inset}
|
|
52
|
+
className={cn(
|
|
53
|
+
'cn-dropdown-menu-checkbox-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
|
54
|
+
className,
|
|
55
|
+
)}
|
|
56
|
+
checked={checked}
|
|
57
|
+
{...props}
|
|
58
|
+
>
|
|
59
|
+
<span
|
|
60
|
+
className="cn-dropdown-menu-item-indicator pointer-events-none"
|
|
61
|
+
data-slot="dropdown-menu-checkbox-item-indicator"
|
|
62
|
+
>
|
|
63
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
64
|
+
<CheckIcon />
|
|
65
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
66
|
+
</span>
|
|
67
|
+
{children}
|
|
68
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
function DropdownMenuRadioGroup({ ...props }) {
|
|
72
|
+
return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
|
|
73
|
+
}
|
|
74
|
+
function DropdownMenuRadioItem({ className, children, inset, ...props }) {
|
|
75
|
+
return (
|
|
76
|
+
<DropdownMenuPrimitive.RadioItem
|
|
77
|
+
data-slot="dropdown-menu-radio-item"
|
|
78
|
+
data-inset={inset}
|
|
79
|
+
className={cn(
|
|
80
|
+
'cn-dropdown-menu-radio-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
|
81
|
+
className,
|
|
82
|
+
)}
|
|
83
|
+
{...props}
|
|
84
|
+
>
|
|
85
|
+
<span
|
|
86
|
+
className="cn-dropdown-menu-item-indicator pointer-events-none"
|
|
87
|
+
data-slot="dropdown-menu-radio-item-indicator"
|
|
88
|
+
>
|
|
89
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
90
|
+
<CheckIcon />
|
|
91
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
92
|
+
</span>
|
|
93
|
+
{children}
|
|
94
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
function DropdownMenuLabel({ className, inset, ...props }) {
|
|
98
|
+
return (
|
|
99
|
+
<DropdownMenuPrimitive.Label
|
|
100
|
+
data-slot="dropdown-menu-label"
|
|
101
|
+
data-inset={inset}
|
|
102
|
+
className={cn('cn-dropdown-menu-label', className)}
|
|
103
|
+
{...props}
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
function DropdownMenuSeparator({ className, ...props }) {
|
|
108
|
+
return (
|
|
109
|
+
<DropdownMenuPrimitive.Separator
|
|
110
|
+
data-slot="dropdown-menu-separator"
|
|
111
|
+
className={cn('cn-dropdown-menu-separator', className)}
|
|
112
|
+
{...props}
|
|
113
|
+
/>
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
function DropdownMenuShortcut({ className, ...props }) {
|
|
117
|
+
return (
|
|
118
|
+
<span
|
|
119
|
+
data-slot="dropdown-menu-shortcut"
|
|
120
|
+
className={cn('cn-dropdown-menu-shortcut', className)}
|
|
121
|
+
{...props}
|
|
122
|
+
/>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
function DropdownMenuSub({ ...props }) {
|
|
126
|
+
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
|
|
127
|
+
}
|
|
128
|
+
function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
|
|
129
|
+
return (
|
|
130
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
131
|
+
data-slot="dropdown-menu-sub-trigger"
|
|
132
|
+
data-inset={inset}
|
|
133
|
+
className={cn(
|
|
134
|
+
'cn-dropdown-menu-sub-trigger flex cursor-default items-center outline-hidden select-none [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
|
135
|
+
className,
|
|
136
|
+
)}
|
|
137
|
+
{...props}
|
|
138
|
+
>
|
|
139
|
+
{children}
|
|
140
|
+
<ChevronRightIcon className="cn-rtl-flip ml-auto" />
|
|
141
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
function DropdownMenuSubContent({ className, ...props }) {
|
|
145
|
+
return (
|
|
146
|
+
<DropdownMenuPrimitive.SubContent
|
|
147
|
+
data-slot="dropdown-menu-sub-content"
|
|
148
|
+
className={cn(
|
|
149
|
+
'cn-dropdown-menu-sub-content cn-menu-target z-50 origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden',
|
|
150
|
+
className,
|
|
151
|
+
)}
|
|
152
|
+
{...props}
|
|
153
|
+
/>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
export {
|
|
157
|
+
DropdownMenu,
|
|
158
|
+
DropdownMenuCheckboxItem,
|
|
159
|
+
DropdownMenuContent,
|
|
160
|
+
DropdownMenuGroup,
|
|
161
|
+
DropdownMenuItem,
|
|
162
|
+
DropdownMenuLabel,
|
|
163
|
+
DropdownMenuPortal,
|
|
164
|
+
DropdownMenuRadioGroup,
|
|
165
|
+
DropdownMenuRadioItem,
|
|
166
|
+
DropdownMenuSeparator,
|
|
167
|
+
DropdownMenuShortcut,
|
|
168
|
+
DropdownMenuSub,
|
|
169
|
+
DropdownMenuSubContent,
|
|
170
|
+
DropdownMenuSubTrigger,
|
|
171
|
+
DropdownMenuTrigger,
|
|
172
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { expect, within } from 'storybook/test';
|
|
3
|
+
import {
|
|
4
|
+
DropdownMenu,
|
|
5
|
+
DropdownMenuTrigger,
|
|
6
|
+
DropdownMenuContent,
|
|
7
|
+
DropdownMenuItem,
|
|
8
|
+
} from './dropdown-menu.jsx';
|
|
9
|
+
import { Button } from './button.jsx';
|
|
10
|
+
const meta = {
|
|
11
|
+
title: 'UI/DropdownMenu',
|
|
12
|
+
component: DropdownMenu,
|
|
13
|
+
};
|
|
14
|
+
var stdin_default = meta;
|
|
15
|
+
const Default = {
|
|
16
|
+
render: () => (
|
|
17
|
+
<DropdownMenu>
|
|
18
|
+
<DropdownMenuTrigger asChild>
|
|
19
|
+
<Button>Open Menu</Button>
|
|
20
|
+
</DropdownMenuTrigger>
|
|
21
|
+
<DropdownMenuContent>
|
|
22
|
+
<DropdownMenuItem>Profile</DropdownMenuItem>
|
|
23
|
+
<DropdownMenuItem>Settings</DropdownMenuItem>
|
|
24
|
+
<DropdownMenuItem>Logout</DropdownMenuItem>
|
|
25
|
+
</DropdownMenuContent>
|
|
26
|
+
</DropdownMenu>
|
|
27
|
+
),
|
|
28
|
+
play: async ({ canvasElement }) => {
|
|
29
|
+
const canvas = within(canvasElement);
|
|
30
|
+
const trigger = canvas.getByRole('button', { name: 'Open Menu' });
|
|
31
|
+
await expect(trigger).toBeInTheDocument();
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
export { Default, stdin_default as default };
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { cva } from 'class-variance-authority';
|
|
3
|
+
import { cn } from './lib/utils.js';
|
|
4
|
+
function Empty({ className, ...props }) {
|
|
5
|
+
return (
|
|
6
|
+
<div
|
|
7
|
+
data-slot="empty"
|
|
8
|
+
className={cn(
|
|
9
|
+
'cn-empty flex w-full min-w-0 flex-1 flex-col items-center justify-center text-center text-balance',
|
|
10
|
+
className,
|
|
11
|
+
)}
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
function EmptyHeader({ className, ...props }) {
|
|
17
|
+
return (
|
|
18
|
+
<div
|
|
19
|
+
data-slot="empty-header"
|
|
20
|
+
className={cn('cn-empty-header flex max-w-sm flex-col items-center', className)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
const emptyMediaVariants = cva(
|
|
26
|
+
'cn-empty-media flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
|
27
|
+
{
|
|
28
|
+
variants: {
|
|
29
|
+
variant: {
|
|
30
|
+
default: 'cn-empty-media-default',
|
|
31
|
+
icon: 'cn-empty-media-icon',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
defaultVariants: {
|
|
35
|
+
variant: 'default',
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
function EmptyMedia({ className, variant = 'default', ...props }) {
|
|
40
|
+
return (
|
|
41
|
+
<div
|
|
42
|
+
data-slot="empty-icon"
|
|
43
|
+
data-variant={variant}
|
|
44
|
+
className={cn(emptyMediaVariants({ variant, className }))}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
function EmptyTitle({ className, ...props }) {
|
|
50
|
+
return <div data-slot="empty-title" className={cn('cn-empty-title', className)} {...props} />;
|
|
51
|
+
}
|
|
52
|
+
function EmptyDescription({ className, ...props }) {
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
data-slot="empty-description"
|
|
56
|
+
className={cn(
|
|
57
|
+
'cn-empty-description text-muted-foreground [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
|
|
58
|
+
className,
|
|
59
|
+
)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
function EmptyContent({ className, ...props }) {
|
|
65
|
+
return (
|
|
66
|
+
<div
|
|
67
|
+
data-slot="empty-content"
|
|
68
|
+
className={cn(
|
|
69
|
+
'cn-empty-content flex w-full max-w-sm min-w-0 flex-col items-center text-balance',
|
|
70
|
+
className,
|
|
71
|
+
)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
export { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { expect } from 'storybook/test';
|
|
3
|
+
import {
|
|
4
|
+
Empty,
|
|
5
|
+
EmptyHeader,
|
|
6
|
+
EmptyTitle,
|
|
7
|
+
EmptyDescription,
|
|
8
|
+
EmptyContent,
|
|
9
|
+
EmptyMedia,
|
|
10
|
+
} from './empty.jsx';
|
|
11
|
+
const meta = {
|
|
12
|
+
title: 'UI/Empty',
|
|
13
|
+
component: Empty,
|
|
14
|
+
};
|
|
15
|
+
var stdin_default = meta;
|
|
16
|
+
const Default = {
|
|
17
|
+
render: () => (
|
|
18
|
+
<Empty>
|
|
19
|
+
<EmptyHeader>
|
|
20
|
+
<EmptyMedia variant="icon">
|
|
21
|
+
<svg
|
|
22
|
+
width="48"
|
|
23
|
+
height="48"
|
|
24
|
+
viewBox="0 0 24 24"
|
|
25
|
+
fill="none"
|
|
26
|
+
stroke="currentColor"
|
|
27
|
+
strokeWidth="2"
|
|
28
|
+
>
|
|
29
|
+
<path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z" />
|
|
30
|
+
</svg>
|
|
31
|
+
</EmptyMedia>
|
|
32
|
+
<EmptyTitle>No items found</EmptyTitle>
|
|
33
|
+
<EmptyDescription>Get started by creating your first item.</EmptyDescription>
|
|
34
|
+
</EmptyHeader>
|
|
35
|
+
</Empty>
|
|
36
|
+
),
|
|
37
|
+
play: async ({ canvasElement }) => {
|
|
38
|
+
const empty = canvasElement.querySelector('[data-slot="empty"]');
|
|
39
|
+
await expect(empty).toBeInTheDocument();
|
|
40
|
+
const title = canvasElement.querySelector('[data-slot="empty-title"]');
|
|
41
|
+
await expect(title).toBeInTheDocument();
|
|
42
|
+
await expect(title.textContent).toBe('No items found');
|
|
43
|
+
const desc = canvasElement.querySelector('[data-slot="empty-description"]');
|
|
44
|
+
await expect(desc.textContent).toBe('Get started by creating your first item.');
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
const WithContent = {
|
|
48
|
+
render: () => (
|
|
49
|
+
<Empty>
|
|
50
|
+
<EmptyHeader>
|
|
51
|
+
<EmptyTitle>Empty state</EmptyTitle>
|
|
52
|
+
<EmptyDescription>Nothing here yet.</EmptyDescription>
|
|
53
|
+
</EmptyHeader>
|
|
54
|
+
<EmptyContent>
|
|
55
|
+
<p>Additional content goes here.</p>
|
|
56
|
+
</EmptyContent>
|
|
57
|
+
</Empty>
|
|
58
|
+
),
|
|
59
|
+
play: async ({ canvasElement }) => {
|
|
60
|
+
const content = canvasElement.querySelector('[data-slot="empty-content"]');
|
|
61
|
+
await expect(content).toBeInTheDocument();
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
export { Default, WithContent, stdin_default as default };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { cva } from 'class-variance-authority';
|
|
4
|
+
import { cn } from './lib/utils.js';
|
|
5
|
+
import { Label } from './label.jsx';
|
|
6
|
+
import { Separator } from './separator.jsx';
|
|
7
|
+
function FieldSet({ className, ...props }) {
|
|
8
|
+
return (
|
|
9
|
+
<fieldset
|
|
10
|
+
data-slot="field-set"
|
|
11
|
+
className={cn('cn-field-set flex flex-col', className)}
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
function FieldLegend({ className, variant = 'legend', ...props }) {
|
|
17
|
+
return (
|
|
18
|
+
<legend
|
|
19
|
+
data-slot="field-legend"
|
|
20
|
+
data-variant={variant}
|
|
21
|
+
className={cn('cn-field-legend', className)}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
function FieldGroup({ className, ...props }) {
|
|
27
|
+
return (
|
|
28
|
+
<div
|
|
29
|
+
data-slot="field-group"
|
|
30
|
+
className={cn(
|
|
31
|
+
'cn-field-group group/field-group @container/field-group flex w-full flex-col',
|
|
32
|
+
className,
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
const fieldVariants = cva('cn-field group/field flex w-full', {
|
|
39
|
+
variants: {
|
|
40
|
+
orientation: {
|
|
41
|
+
vertical: 'cn-field-orientation-vertical flex-col *:w-full [&>.sr-only]:w-auto',
|
|
42
|
+
horizontal:
|
|
43
|
+
'cn-field-orientation-horizontal flex-row items-center *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',
|
|
44
|
+
responsive:
|
|
45
|
+
'cn-field-orientation-responsive flex-col *:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:*:data-[slot=field-label]:flex-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
defaultVariants: {
|
|
49
|
+
orientation: 'vertical',
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
function Field({ className, orientation = 'vertical', ...props }) {
|
|
53
|
+
return (
|
|
54
|
+
<div
|
|
55
|
+
role="group"
|
|
56
|
+
data-slot="field"
|
|
57
|
+
data-orientation={orientation}
|
|
58
|
+
className={cn(fieldVariants({ orientation }), className)}
|
|
59
|
+
{...props}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
function FieldContent({ className, ...props }) {
|
|
64
|
+
return (
|
|
65
|
+
<div
|
|
66
|
+
data-slot="field-content"
|
|
67
|
+
className={cn(
|
|
68
|
+
'cn-field-content group/field-content flex flex-1 flex-col leading-snug',
|
|
69
|
+
className,
|
|
70
|
+
)}
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
function FieldLabel({ className, ...props }) {
|
|
76
|
+
return (
|
|
77
|
+
<Label
|
|
78
|
+
data-slot="field-label"
|
|
79
|
+
className={cn(
|
|
80
|
+
'cn-field-label group/field-label peer/field-label flex w-fit leading-snug',
|
|
81
|
+
'has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col',
|
|
82
|
+
className,
|
|
83
|
+
)}
|
|
84
|
+
{...props}
|
|
85
|
+
/>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
function FieldTitle({ className, ...props }) {
|
|
89
|
+
return (
|
|
90
|
+
<div
|
|
91
|
+
data-slot="field-label"
|
|
92
|
+
className={cn('cn-field-title flex w-fit items-center leading-snug', className)}
|
|
93
|
+
{...props}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
function FieldDescription({ className, ...props }) {
|
|
98
|
+
return (
|
|
99
|
+
<p
|
|
100
|
+
data-slot="field-description"
|
|
101
|
+
className={cn(
|
|
102
|
+
'cn-field-description leading-normal font-normal group-has-data-horizontal/field:text-balance',
|
|
103
|
+
'last:mt-0 nth-last-2:-mt-1',
|
|
104
|
+
'[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4',
|
|
105
|
+
className,
|
|
106
|
+
)}
|
|
107
|
+
{...props}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
function FieldSeparator({ children, className, ...props }) {
|
|
112
|
+
return (
|
|
113
|
+
<div
|
|
114
|
+
data-slot="field-separator"
|
|
115
|
+
data-content={!!children}
|
|
116
|
+
className={cn('cn-field-separator relative', className)}
|
|
117
|
+
{...props}
|
|
118
|
+
>
|
|
119
|
+
<Separator className="absolute inset-0 top-1/2" />
|
|
120
|
+
{children && (
|
|
121
|
+
<span
|
|
122
|
+
className="cn-field-separator-content bg-background relative mx-auto block w-fit"
|
|
123
|
+
data-slot="field-separator-content"
|
|
124
|
+
>
|
|
125
|
+
{children}
|
|
126
|
+
</span>
|
|
127
|
+
)}
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
function FieldError({ className, children, errors, ...props }) {
|
|
132
|
+
const content = useMemo(() => {
|
|
133
|
+
if (children) {
|
|
134
|
+
return children;
|
|
135
|
+
}
|
|
136
|
+
if (!errors?.length) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
const uniqueErrors = [...new Map(errors.map((error) => [error?.message, error])).values()];
|
|
140
|
+
if (uniqueErrors?.length == 1) {
|
|
141
|
+
return uniqueErrors[0]?.message;
|
|
142
|
+
}
|
|
143
|
+
return (
|
|
144
|
+
<ul className="ml-4 flex list-disc flex-col gap-1">
|
|
145
|
+
{uniqueErrors.map((error, index) => error?.message && <li key={index}>{error.message}</li>)}
|
|
146
|
+
</ul>
|
|
147
|
+
);
|
|
148
|
+
}, [children, errors]);
|
|
149
|
+
if (!content) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
return (
|
|
153
|
+
<div
|
|
154
|
+
role="alert"
|
|
155
|
+
data-slot="field-error"
|
|
156
|
+
className={cn('cn-field-error font-normal', className)}
|
|
157
|
+
{...props}
|
|
158
|
+
>
|
|
159
|
+
{content}
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
export {
|
|
164
|
+
Field,
|
|
165
|
+
FieldContent,
|
|
166
|
+
FieldDescription,
|
|
167
|
+
FieldError,
|
|
168
|
+
FieldGroup,
|
|
169
|
+
FieldLabel,
|
|
170
|
+
FieldLegend,
|
|
171
|
+
FieldSeparator,
|
|
172
|
+
FieldSet,
|
|
173
|
+
FieldTitle,
|
|
174
|
+
};
|