@cogito.ai/cli 0.3.5 → 0.4.1

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 (71) hide show
  1. package/dist/index.js +20 -1
  2. package/dist/templates/web-nextjs/apps/docs/.source/browser.ts +1 -1
  3. package/dist/templates/web-nextjs/apps/docs/.source/server.ts +3 -2
  4. package/dist/templates/web-nextjs/apps/docs/content/docs/decisions/meta.json +1 -1
  5. package/dist/templates/web-nextjs/apps/docs/content/docs/decisions/turbo-package-manager.mdx +70 -0
  6. package/dist/templates/web-nextjs/apps/docs/package.json +1 -1
  7. package/dist/templates/web-nextjs/apps/web/messages/en.json +5 -1
  8. package/dist/templates/web-nextjs/apps/web/messages/zh.json +5 -1
  9. package/dist/templates/web-nextjs/apps/web/package.json +27 -0
  10. package/dist/templates/web-nextjs/apps/web/postcss.config.mjs +8 -0
  11. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/login/page.tsx +87 -93
  12. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(auth)/signup/page.tsx +116 -98
  13. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/dashboard/page.tsx +38 -29
  14. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/(protected)/layout.tsx +2 -5
  15. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/layout.tsx +4 -7
  16. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/privacy/page.tsx +23 -0
  17. package/dist/templates/web-nextjs/apps/web/src/app/[locale]/terms/page.tsx +23 -0
  18. package/dist/templates/web-nextjs/apps/web/src/app/route.ts +13 -0
  19. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/app-sidebar.tsx +188 -0
  20. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/chart-area-interactive.tsx +291 -0
  21. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/data-table.tsx +807 -0
  22. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/data.json +614 -0
  23. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-documents.tsx +92 -0
  24. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-main.tsx +58 -0
  25. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-secondary.tsx +42 -0
  26. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/nav-user.tsx +118 -0
  27. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/page.tsx +40 -0
  28. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/section-cards.tsx +102 -0
  29. package/dist/templates/web-nextjs/apps/web/src/components/dashboard/site-header.tsx +30 -0
  30. package/dist/templates/web-nextjs/apps/web/src/components/ui/alert-dialog.tsx +196 -0
  31. package/dist/templates/web-nextjs/apps/web/src/components/ui/avatar.tsx +109 -0
  32. package/dist/templates/web-nextjs/apps/web/src/components/ui/badge.tsx +48 -0
  33. package/dist/templates/web-nextjs/apps/web/src/components/ui/breadcrumb.tsx +109 -0
  34. package/dist/templates/web-nextjs/apps/web/src/components/ui/button.tsx +14 -2
  35. package/dist/templates/web-nextjs/apps/web/src/components/ui/card.tsx +92 -0
  36. package/dist/templates/web-nextjs/apps/web/src/components/ui/chart.tsx +374 -0
  37. package/dist/templates/web-nextjs/apps/web/src/components/ui/checkbox.tsx +32 -0
  38. package/dist/templates/web-nextjs/apps/web/src/components/ui/collapsible.tsx +33 -0
  39. package/dist/templates/web-nextjs/apps/web/src/components/ui/command.tsx +184 -0
  40. package/dist/templates/web-nextjs/apps/web/src/components/ui/dialog.tsx +158 -0
  41. package/dist/templates/web-nextjs/apps/web/src/components/ui/drawer.tsx +135 -0
  42. package/dist/templates/web-nextjs/apps/web/src/components/ui/dropdown-menu.tsx +257 -0
  43. package/dist/templates/web-nextjs/apps/web/src/components/ui/field.tsx +248 -0
  44. package/dist/templates/web-nextjs/apps/web/src/components/ui/input-otp.tsx +77 -0
  45. package/dist/templates/web-nextjs/apps/web/src/components/ui/pagination.tsx +127 -0
  46. package/dist/templates/web-nextjs/apps/web/src/components/ui/popover.tsx +89 -0
  47. package/dist/templates/web-nextjs/apps/web/src/components/ui/progress.tsx +31 -0
  48. package/dist/templates/web-nextjs/apps/web/src/components/ui/radio-group.tsx +45 -0
  49. package/dist/templates/web-nextjs/apps/web/src/components/ui/scroll-area.tsx +58 -0
  50. package/dist/templates/web-nextjs/apps/web/src/components/ui/select.tsx +190 -0
  51. package/dist/templates/web-nextjs/apps/web/src/components/ui/separator.tsx +29 -0
  52. package/dist/templates/web-nextjs/apps/web/src/components/ui/sheet.tsx +143 -0
  53. package/dist/templates/web-nextjs/apps/web/src/components/ui/sidebar.tsx +726 -0
  54. package/dist/templates/web-nextjs/apps/web/src/components/ui/skeleton.tsx +13 -0
  55. package/dist/templates/web-nextjs/apps/web/src/components/ui/slider.tsx +63 -0
  56. package/dist/templates/web-nextjs/apps/web/src/components/ui/sonner.tsx +11 -25
  57. package/dist/templates/web-nextjs/apps/web/src/components/ui/switch.tsx +35 -0
  58. package/dist/templates/web-nextjs/apps/web/src/components/ui/table.tsx +116 -0
  59. package/dist/templates/web-nextjs/apps/web/src/components/ui/tabs.tsx +91 -0
  60. package/dist/templates/web-nextjs/apps/web/src/components/ui/textarea.tsx +18 -0
  61. package/dist/templates/web-nextjs/apps/web/src/components/ui/toggle-group.tsx +83 -0
  62. package/dist/templates/web-nextjs/apps/web/src/components/ui/toggle.tsx +47 -0
  63. package/dist/templates/web-nextjs/apps/web/src/components/ui/tooltip.tsx +57 -0
  64. package/dist/templates/web-nextjs/apps/web/src/features/auth/server.ts +15 -0
  65. package/dist/templates/web-nextjs/apps/web/src/hooks/use-mobile.ts +21 -0
  66. package/dist/templates/web-nextjs/package.json +10 -0
  67. package/dist/templates/web-nextjs/packages/openspec-docs-sync/package.json +0 -3
  68. package/dist/templates/web-nextjs/pnpm-lock.yaml +1561 -96
  69. package/dist/templates/web-nextjs/pnpm-workspace.yaml +15 -0
  70. package/dist/templates/web-nextjs/turbo.json +1 -0
  71. package/package.json +2 -2
@@ -0,0 +1,58 @@
1
+ "use client"
2
+
3
+ import { IconCirclePlusFilled, IconMail, type Icon } from "@tabler/icons-react"
4
+
5
+ import { Button } from "@/components/ui/button"
6
+ import {
7
+ SidebarGroup,
8
+ SidebarGroupContent,
9
+ SidebarMenu,
10
+ SidebarMenuButton,
11
+ SidebarMenuItem,
12
+ } from "@/components/ui/sidebar"
13
+
14
+ export function NavMain({
15
+ items,
16
+ }: {
17
+ items: {
18
+ title: string
19
+ url: string
20
+ icon?: Icon
21
+ }[]
22
+ }) {
23
+ return (
24
+ <SidebarGroup>
25
+ <SidebarGroupContent className="flex flex-col gap-2">
26
+ <SidebarMenu>
27
+ <SidebarMenuItem className="flex items-center gap-2">
28
+ <SidebarMenuButton
29
+ tooltip="Quick Create"
30
+ className="min-w-8 bg-primary text-primary-foreground duration-200 ease-linear hover:bg-primary/90 hover:text-primary-foreground active:bg-primary/90 active:text-primary-foreground"
31
+ >
32
+ <IconCirclePlusFilled />
33
+ <span>Quick Create</span>
34
+ </SidebarMenuButton>
35
+ <Button
36
+ size="icon"
37
+ className="size-8 group-data-[collapsible=icon]:opacity-0"
38
+ variant="outline"
39
+ >
40
+ <IconMail />
41
+ <span className="sr-only">Inbox</span>
42
+ </Button>
43
+ </SidebarMenuItem>
44
+ </SidebarMenu>
45
+ <SidebarMenu>
46
+ {items.map((item) => (
47
+ <SidebarMenuItem key={item.title}>
48
+ <SidebarMenuButton tooltip={item.title}>
49
+ {item.icon && <item.icon />}
50
+ <span>{item.title}</span>
51
+ </SidebarMenuButton>
52
+ </SidebarMenuItem>
53
+ ))}
54
+ </SidebarMenu>
55
+ </SidebarGroupContent>
56
+ </SidebarGroup>
57
+ )
58
+ }
@@ -0,0 +1,42 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { type Icon } from "@tabler/icons-react"
5
+
6
+ import {
7
+ SidebarGroup,
8
+ SidebarGroupContent,
9
+ SidebarMenu,
10
+ SidebarMenuButton,
11
+ SidebarMenuItem,
12
+ } from "@/components/ui/sidebar"
13
+
14
+ export function NavSecondary({
15
+ items,
16
+ ...props
17
+ }: {
18
+ items: {
19
+ title: string
20
+ url: string
21
+ icon: Icon
22
+ }[]
23
+ } & React.ComponentPropsWithoutRef<typeof SidebarGroup>) {
24
+ return (
25
+ <SidebarGroup {...props}>
26
+ <SidebarGroupContent>
27
+ <SidebarMenu>
28
+ {items.map((item) => (
29
+ <SidebarMenuItem key={item.title}>
30
+ <SidebarMenuButton asChild>
31
+ <a href={item.url}>
32
+ <item.icon />
33
+ <span>{item.title}</span>
34
+ </a>
35
+ </SidebarMenuButton>
36
+ </SidebarMenuItem>
37
+ ))}
38
+ </SidebarMenu>
39
+ </SidebarGroupContent>
40
+ </SidebarGroup>
41
+ )
42
+ }
@@ -0,0 +1,118 @@
1
+ "use client"
2
+
3
+ import {
4
+ IconCreditCard,
5
+ IconDotsVertical,
6
+ IconLogout,
7
+ IconNotification,
8
+ IconUserCircle,
9
+ } from "@tabler/icons-react"
10
+
11
+ import {
12
+ Avatar,
13
+ AvatarFallback,
14
+ AvatarImage,
15
+ } from "@/components/ui/avatar"
16
+ import {
17
+ DropdownMenu,
18
+ DropdownMenuContent,
19
+ DropdownMenuGroup,
20
+ DropdownMenuItem,
21
+ DropdownMenuLabel,
22
+ DropdownMenuSeparator,
23
+ DropdownMenuTrigger,
24
+ } from "@/components/ui/dropdown-menu"
25
+ import {
26
+ SidebarMenu,
27
+ SidebarMenuButton,
28
+ SidebarMenuItem,
29
+ useSidebar,
30
+ } from "@/components/ui/sidebar"
31
+ import { signOut } from '@/features/auth'
32
+
33
+ export function NavUser({
34
+ user,
35
+ locale,
36
+ }: {
37
+ user: {
38
+ name: string
39
+ email: string
40
+ avatar: string
41
+ }
42
+ locale: string
43
+ }) {
44
+ const { isMobile } = useSidebar()
45
+
46
+ return (
47
+ <SidebarMenu>
48
+ <SidebarMenuItem>
49
+ <DropdownMenu>
50
+ <DropdownMenuTrigger asChild>
51
+ <SidebarMenuButton
52
+ size="lg"
53
+ className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
54
+ >
55
+ <Avatar className="h-8 w-8 rounded-lg grayscale">
56
+ <AvatarImage src={user.avatar} alt={user.name} />
57
+ <AvatarFallback className="rounded-lg">CN</AvatarFallback>
58
+ </Avatar>
59
+ <div className="grid flex-1 text-left text-sm leading-tight">
60
+ <span className="truncate font-medium">{user.name}</span>
61
+ <span className="truncate text-xs text-muted-foreground">
62
+ {user.email}
63
+ </span>
64
+ </div>
65
+ <IconDotsVertical className="ml-auto size-4" />
66
+ </SidebarMenuButton>
67
+ </DropdownMenuTrigger>
68
+ <DropdownMenuContent
69
+ className="w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg"
70
+ side={isMobile ? "bottom" : "right"}
71
+ align="end"
72
+ sideOffset={4}
73
+ >
74
+ <DropdownMenuLabel className="p-0 font-normal">
75
+ <div className="flex items-center gap-2 px-1 py-1.5 text-left text-sm">
76
+ <Avatar className="h-8 w-8 rounded-lg">
77
+ <AvatarImage src={user.avatar} alt={user.name} />
78
+ <AvatarFallback className="rounded-lg">CN</AvatarFallback>
79
+ </Avatar>
80
+ <div className="grid flex-1 text-left text-sm leading-tight">
81
+ <span className="truncate font-medium">{user.name}</span>
82
+ <span className="truncate text-xs text-muted-foreground">
83
+ {user.email}
84
+ </span>
85
+ </div>
86
+ </div>
87
+ </DropdownMenuLabel>
88
+ <DropdownMenuSeparator />
89
+ <DropdownMenuGroup>
90
+ <DropdownMenuItem>
91
+ <IconUserCircle />
92
+ Account
93
+ </DropdownMenuItem>
94
+ <DropdownMenuItem>
95
+ <IconCreditCard />
96
+ Billing
97
+ </DropdownMenuItem>
98
+ <DropdownMenuItem>
99
+ <IconNotification />
100
+ Notifications
101
+ </DropdownMenuItem>
102
+ </DropdownMenuGroup>
103
+ <DropdownMenuSeparator />
104
+ <DropdownMenuItem asChild>
105
+ <form action={signOut}>
106
+ <input type="hidden" name="locale" value={locale} />
107
+ <button type="submit" className="flex w-full items-center gap-2">
108
+ <IconLogout />
109
+ Log out
110
+ </button>
111
+ </form>
112
+ </DropdownMenuItem>
113
+ </DropdownMenuContent>
114
+ </DropdownMenu>
115
+ </SidebarMenuItem>
116
+ </SidebarMenu>
117
+ )
118
+ }
@@ -0,0 +1,40 @@
1
+ import { AppSidebar } from "@/components/dashboard/app-sidebar"
2
+ import { ChartAreaInteractive } from "@/components/dashboard/chart-area-interactive"
3
+ import { DataTable } from "@/components/dashboard/data-table"
4
+ import { SectionCards } from "@/components/dashboard/section-cards"
5
+ import { SiteHeader } from "@/components/dashboard/site-header"
6
+ import {
7
+ SidebarInset,
8
+ SidebarProvider,
9
+ } from "@/components/ui/sidebar"
10
+
11
+ import data from "./data.json"
12
+
13
+ export default function Page() {
14
+ return (
15
+ <SidebarProvider
16
+ style={
17
+ {
18
+ "--sidebar-width": "calc(var(--spacing) * 72)",
19
+ "--header-height": "calc(var(--spacing) * 12)",
20
+ } as React.CSSProperties
21
+ }
22
+ >
23
+ <AppSidebar variant="inset" user={{ name: "User", email: "", avatar: "" }} locale="en" />
24
+ <SidebarInset>
25
+ <SiteHeader />
26
+ <div className="flex flex-1 flex-col">
27
+ <div className="@container/main flex flex-1 flex-col gap-2">
28
+ <div className="flex flex-col gap-4 py-4 md:gap-6 md:py-6">
29
+ <SectionCards />
30
+ <div className="px-4 lg:px-6">
31
+ <ChartAreaInteractive />
32
+ </div>
33
+ <DataTable data={data} />
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </SidebarInset>
38
+ </SidebarProvider>
39
+ )
40
+ }
@@ -0,0 +1,102 @@
1
+ import { IconTrendingDown, IconTrendingUp } from "@tabler/icons-react"
2
+
3
+ import { Badge } from "@/components/ui/badge"
4
+ import {
5
+ Card,
6
+ CardAction,
7
+ CardDescription,
8
+ CardFooter,
9
+ CardHeader,
10
+ CardTitle,
11
+ } from "@/components/ui/card"
12
+
13
+ export function SectionCards() {
14
+ return (
15
+ <div className="grid grid-cols-1 gap-4 px-4 *:data-[slot=card]:bg-gradient-to-t *:data-[slot=card]:from-primary/5 *:data-[slot=card]:to-card *:data-[slot=card]:shadow-xs lg:px-6 @xl/main:grid-cols-2 @5xl/main:grid-cols-4 dark:*:data-[slot=card]:bg-card">
16
+ <Card className="@container/card">
17
+ <CardHeader>
18
+ <CardDescription>Total Revenue</CardDescription>
19
+ <CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
20
+ $1,250.00
21
+ </CardTitle>
22
+ <CardAction>
23
+ <Badge variant="outline">
24
+ <IconTrendingUp />
25
+ +12.5%
26
+ </Badge>
27
+ </CardAction>
28
+ </CardHeader>
29
+ <CardFooter className="flex-col items-start gap-1.5 text-sm">
30
+ <div className="line-clamp-1 flex gap-2 font-medium">
31
+ Trending up this month <IconTrendingUp className="size-4" />
32
+ </div>
33
+ <div className="text-muted-foreground">
34
+ Visitors for the last 6 months
35
+ </div>
36
+ </CardFooter>
37
+ </Card>
38
+ <Card className="@container/card">
39
+ <CardHeader>
40
+ <CardDescription>New Customers</CardDescription>
41
+ <CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
42
+ 1,234
43
+ </CardTitle>
44
+ <CardAction>
45
+ <Badge variant="outline">
46
+ <IconTrendingDown />
47
+ -20%
48
+ </Badge>
49
+ </CardAction>
50
+ </CardHeader>
51
+ <CardFooter className="flex-col items-start gap-1.5 text-sm">
52
+ <div className="line-clamp-1 flex gap-2 font-medium">
53
+ Down 20% this period <IconTrendingDown className="size-4" />
54
+ </div>
55
+ <div className="text-muted-foreground">
56
+ Acquisition needs attention
57
+ </div>
58
+ </CardFooter>
59
+ </Card>
60
+ <Card className="@container/card">
61
+ <CardHeader>
62
+ <CardDescription>Active Accounts</CardDescription>
63
+ <CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
64
+ 45,678
65
+ </CardTitle>
66
+ <CardAction>
67
+ <Badge variant="outline">
68
+ <IconTrendingUp />
69
+ +12.5%
70
+ </Badge>
71
+ </CardAction>
72
+ </CardHeader>
73
+ <CardFooter className="flex-col items-start gap-1.5 text-sm">
74
+ <div className="line-clamp-1 flex gap-2 font-medium">
75
+ Strong user retention <IconTrendingUp className="size-4" />
76
+ </div>
77
+ <div className="text-muted-foreground">Engagement exceed targets</div>
78
+ </CardFooter>
79
+ </Card>
80
+ <Card className="@container/card">
81
+ <CardHeader>
82
+ <CardDescription>Growth Rate</CardDescription>
83
+ <CardTitle className="text-2xl font-semibold tabular-nums @[250px]/card:text-3xl">
84
+ 4.5%
85
+ </CardTitle>
86
+ <CardAction>
87
+ <Badge variant="outline">
88
+ <IconTrendingUp />
89
+ +4.5%
90
+ </Badge>
91
+ </CardAction>
92
+ </CardHeader>
93
+ <CardFooter className="flex-col items-start gap-1.5 text-sm">
94
+ <div className="line-clamp-1 flex gap-2 font-medium">
95
+ Steady performance increase <IconTrendingUp className="size-4" />
96
+ </div>
97
+ <div className="text-muted-foreground">Meets growth projections</div>
98
+ </CardFooter>
99
+ </Card>
100
+ </div>
101
+ )
102
+ }
@@ -0,0 +1,30 @@
1
+ import { Button } from "@/components/ui/button"
2
+ import { Separator } from "@/components/ui/separator"
3
+ import { SidebarTrigger } from "@/components/ui/sidebar"
4
+
5
+ export function SiteHeader() {
6
+ return (
7
+ <header className="flex h-(--header-height) shrink-0 items-center gap-2 border-b transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-(--header-height)">
8
+ <div className="flex w-full items-center gap-1 px-4 lg:gap-2 lg:px-6">
9
+ <SidebarTrigger className="-ml-1" />
10
+ <Separator
11
+ orientation="vertical"
12
+ className="mx-2 data-[orientation=vertical]:h-4"
13
+ />
14
+ <h1 className="text-base font-medium">Documents</h1>
15
+ <div className="ml-auto flex items-center gap-2">
16
+ <Button variant="ghost" asChild size="sm" className="hidden sm:flex">
17
+ <a
18
+ href="https://github.com/shadcn-ui/ui/tree/main/apps/v4/app/(examples)/dashboard"
19
+ rel="noopener noreferrer"
20
+ target="_blank"
21
+ className="dark:text-foreground"
22
+ >
23
+ GitHub
24
+ </a>
25
+ </Button>
26
+ </div>
27
+ </div>
28
+ </header>
29
+ )
30
+ }
@@ -0,0 +1,196 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { AlertDialog as AlertDialogPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { Button } from "@/components/ui/button"
8
+
9
+ function AlertDialog({
10
+ ...props
11
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Root>) {
12
+ return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />
13
+ }
14
+
15
+ function AlertDialogTrigger({
16
+ ...props
17
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Trigger>) {
18
+ return (
19
+ <AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
20
+ )
21
+ }
22
+
23
+ function AlertDialogPortal({
24
+ ...props
25
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Portal>) {
26
+ return (
27
+ <AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
28
+ )
29
+ }
30
+
31
+ function AlertDialogOverlay({
32
+ className,
33
+ ...props
34
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Overlay>) {
35
+ return (
36
+ <AlertDialogPrimitive.Overlay
37
+ data-slot="alert-dialog-overlay"
38
+ className={cn(
39
+ "fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
40
+ className
41
+ )}
42
+ {...props}
43
+ />
44
+ )
45
+ }
46
+
47
+ function AlertDialogContent({
48
+ className,
49
+ size = "default",
50
+ ...props
51
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Content> & {
52
+ size?: "default" | "sm"
53
+ }) {
54
+ return (
55
+ <AlertDialogPortal>
56
+ <AlertDialogOverlay />
57
+ <AlertDialogPrimitive.Content
58
+ data-slot="alert-dialog-content"
59
+ data-size={size}
60
+ className={cn(
61
+ "group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 shadow-lg duration-200 data-[size=sm]:max-w-xs data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 data-[size=default]:sm:max-w-lg",
62
+ className
63
+ )}
64
+ {...props}
65
+ />
66
+ </AlertDialogPortal>
67
+ )
68
+ }
69
+
70
+ function AlertDialogHeader({
71
+ className,
72
+ ...props
73
+ }: React.ComponentProps<"div">) {
74
+ return (
75
+ <div
76
+ data-slot="alert-dialog-header"
77
+ className={cn(
78
+ "grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
79
+ className
80
+ )}
81
+ {...props}
82
+ />
83
+ )
84
+ }
85
+
86
+ function AlertDialogFooter({
87
+ className,
88
+ ...props
89
+ }: React.ComponentProps<"div">) {
90
+ return (
91
+ <div
92
+ data-slot="alert-dialog-footer"
93
+ className={cn(
94
+ "flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end",
95
+ className
96
+ )}
97
+ {...props}
98
+ />
99
+ )
100
+ }
101
+
102
+ function AlertDialogTitle({
103
+ className,
104
+ ...props
105
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {
106
+ return (
107
+ <AlertDialogPrimitive.Title
108
+ data-slot="alert-dialog-title"
109
+ className={cn(
110
+ "text-lg font-semibold sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
111
+ className
112
+ )}
113
+ {...props}
114
+ />
115
+ )
116
+ }
117
+
118
+ function AlertDialogDescription({
119
+ className,
120
+ ...props
121
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {
122
+ return (
123
+ <AlertDialogPrimitive.Description
124
+ data-slot="alert-dialog-description"
125
+ className={cn("text-sm text-muted-foreground", className)}
126
+ {...props}
127
+ />
128
+ )
129
+ }
130
+
131
+ function AlertDialogMedia({
132
+ className,
133
+ ...props
134
+ }: React.ComponentProps<"div">) {
135
+ return (
136
+ <div
137
+ data-slot="alert-dialog-media"
138
+ className={cn(
139
+ "mb-2 inline-flex size-16 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8",
140
+ className
141
+ )}
142
+ {...props}
143
+ />
144
+ )
145
+ }
146
+
147
+ function AlertDialogAction({
148
+ className,
149
+ variant = "default",
150
+ size = "default",
151
+ ...props
152
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Action> &
153
+ Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
154
+ return (
155
+ <Button variant={variant} size={size} asChild>
156
+ <AlertDialogPrimitive.Action
157
+ data-slot="alert-dialog-action"
158
+ className={cn(className)}
159
+ {...props}
160
+ />
161
+ </Button>
162
+ )
163
+ }
164
+
165
+ function AlertDialogCancel({
166
+ className,
167
+ variant = "outline",
168
+ size = "default",
169
+ ...props
170
+ }: React.ComponentProps<typeof AlertDialogPrimitive.Cancel> &
171
+ Pick<React.ComponentProps<typeof Button>, "variant" | "size">) {
172
+ return (
173
+ <Button variant={variant} size={size} asChild>
174
+ <AlertDialogPrimitive.Cancel
175
+ data-slot="alert-dialog-cancel"
176
+ className={cn(className)}
177
+ {...props}
178
+ />
179
+ </Button>
180
+ )
181
+ }
182
+
183
+ export {
184
+ AlertDialog,
185
+ AlertDialogAction,
186
+ AlertDialogCancel,
187
+ AlertDialogContent,
188
+ AlertDialogDescription,
189
+ AlertDialogFooter,
190
+ AlertDialogHeader,
191
+ AlertDialogMedia,
192
+ AlertDialogOverlay,
193
+ AlertDialogPortal,
194
+ AlertDialogTitle,
195
+ AlertDialogTrigger,
196
+ }
@@ -0,0 +1,109 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Avatar as AvatarPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ function Avatar({
9
+ className,
10
+ size = "default",
11
+ ...props
12
+ }: React.ComponentProps<typeof AvatarPrimitive.Root> & {
13
+ size?: "default" | "sm" | "lg"
14
+ }) {
15
+ return (
16
+ <AvatarPrimitive.Root
17
+ data-slot="avatar"
18
+ data-size={size}
19
+ className={cn(
20
+ "group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
21
+ className
22
+ )}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ function AvatarImage({
29
+ className,
30
+ ...props
31
+ }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
32
+ return (
33
+ <AvatarPrimitive.Image
34
+ data-slot="avatar-image"
35
+ className={cn("aspect-square size-full", className)}
36
+ {...props}
37
+ />
38
+ )
39
+ }
40
+
41
+ function AvatarFallback({
42
+ className,
43
+ ...props
44
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
45
+ return (
46
+ <AvatarPrimitive.Fallback
47
+ data-slot="avatar-fallback"
48
+ className={cn(
49
+ "flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs",
50
+ className
51
+ )}
52
+ {...props}
53
+ />
54
+ )
55
+ }
56
+
57
+ function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
58
+ return (
59
+ <span
60
+ data-slot="avatar-badge"
61
+ className={cn(
62
+ "absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground ring-2 ring-background select-none",
63
+ "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
64
+ "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
65
+ "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
66
+ className
67
+ )}
68
+ {...props}
69
+ />
70
+ )
71
+ }
72
+
73
+ function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
74
+ return (
75
+ <div
76
+ data-slot="avatar-group"
77
+ className={cn(
78
+ "group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background",
79
+ className
80
+ )}
81
+ {...props}
82
+ />
83
+ )
84
+ }
85
+
86
+ function AvatarGroupCount({
87
+ className,
88
+ ...props
89
+ }: React.ComponentProps<"div">) {
90
+ return (
91
+ <div
92
+ data-slot="avatar-group-count"
93
+ className={cn(
94
+ "relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
95
+ className
96
+ )}
97
+ {...props}
98
+ />
99
+ )
100
+ }
101
+
102
+ export {
103
+ Avatar,
104
+ AvatarImage,
105
+ AvatarFallback,
106
+ AvatarBadge,
107
+ AvatarGroup,
108
+ AvatarGroupCount,
109
+ }