create-aron-app 0.1.0 → 0.1.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 (156) hide show
  1. package/package.json +5 -2
  2. package/templates/_base/.cursor/agents/skills/clerk/SKILL.md +89 -0
  3. package/templates/_base/.cursor/agents/skills/clerk/clerk-backend-api/SKILL.md +142 -0
  4. package/templates/_base/.cursor/agents/skills/clerk/clerk-backend-api/scripts/api-specs-context.sh +30 -0
  5. package/templates/_base/.cursor/agents/skills/clerk/clerk-backend-api/scripts/execute-request.sh +88 -0
  6. package/templates/_base/.cursor/agents/skills/clerk/clerk-backend-api/scripts/extract-endpoint-detail.sh +165 -0
  7. package/templates/_base/.cursor/agents/skills/clerk/clerk-backend-api/scripts/extract-tag-endpoints.sh +208 -0
  8. package/templates/_base/.cursor/agents/skills/clerk/clerk-backend-api/scripts/extract-tags.js +14 -0
  9. package/templates/_base/.cursor/agents/skills/clerk/clerk-custom-ui/SKILL.md +157 -0
  10. package/templates/_base/.cursor/agents/skills/clerk/clerk-custom-ui/core-2/custom-sign-in.md +224 -0
  11. package/templates/_base/.cursor/agents/skills/clerk/clerk-custom-ui/core-2/custom-sign-up.md +190 -0
  12. package/templates/_base/.cursor/agents/skills/clerk/clerk-custom-ui/core-3/custom-sign-in.md +314 -0
  13. package/templates/_base/.cursor/agents/skills/clerk/clerk-custom-ui/core-3/custom-sign-up.md +259 -0
  14. package/templates/_base/.cursor/agents/skills/clerk/clerk-custom-ui/core-3/show-component.md +125 -0
  15. package/templates/_base/.cursor/agents/skills/clerk/clerk-nextjs-patterns/SKILL.md +94 -0
  16. package/templates/_base/.cursor/agents/skills/clerk/clerk-nextjs-patterns/references/api-routes.md +50 -0
  17. package/templates/_base/.cursor/agents/skills/clerk/clerk-nextjs-patterns/references/caching-auth.md +56 -0
  18. package/templates/_base/.cursor/agents/skills/clerk/clerk-nextjs-patterns/references/middleware-strategies.md +68 -0
  19. package/templates/_base/.cursor/agents/skills/clerk/clerk-nextjs-patterns/references/server-actions.md +56 -0
  20. package/templates/_base/.cursor/agents/skills/clerk/clerk-nextjs-patterns/references/server-vs-client.md +104 -0
  21. package/templates/_base/.cursor/agents/skills/clerk/clerk-webhooks/SKILL.md +131 -0
  22. package/templates/_base/.cursor/agents/skills/shadcn/SKILL.md +241 -0
  23. package/templates/_base/.cursor/agents/skills/shadcn/agents/openai.yml +5 -0
  24. package/templates/_base/.cursor/agents/skills/shadcn/assets/shadcn-small.png +0 -0
  25. package/templates/_base/.cursor/agents/skills/shadcn/assets/shadcn.png +0 -0
  26. package/templates/_base/.cursor/agents/skills/shadcn/cli.md +257 -0
  27. package/templates/_base/.cursor/agents/skills/shadcn/customization.md +202 -0
  28. package/templates/_base/.cursor/agents/skills/shadcn/evals/evals.json +47 -0
  29. package/templates/_base/.cursor/agents/skills/shadcn/mcp.md +94 -0
  30. package/templates/_base/.cursor/agents/skills/shadcn/rules/base-vs-radix.md +306 -0
  31. package/templates/_base/.cursor/agents/skills/shadcn/rules/composition.md +195 -0
  32. package/templates/_base/.cursor/agents/skills/shadcn/rules/forms.md +192 -0
  33. package/templates/_base/.cursor/agents/skills/shadcn/rules/icons.md +101 -0
  34. package/templates/_base/.cursor/agents/skills/shadcn/rules/styling.md +162 -0
  35. package/templates/_base/.cursor/commands/builder.md +0 -0
  36. package/templates/_base/.cursor/commands/pr.md +7 -0
  37. package/templates/_base/.cursor/rules/api_architecture.mdc +268 -0
  38. package/templates/_base/.cursor/rules/coding_standards.mdc +64 -0
  39. package/templates/_base/.cursor/rules/convex_rules.mdc +675 -0
  40. package/templates/_base/.cursor/rules/frontend_rules.mdc +268 -0
  41. package/templates/_base/.env.convex.example +3 -0
  42. package/templates/_base/.github/workflows/ci.yml +29 -0
  43. package/templates/_base/.nvmrc +1 -0
  44. package/templates/_base/.vscode/settings.json +9 -0
  45. package/templates/_base/apps/api/auth.config.ts +18 -0
  46. package/templates/_base/apps/api/functions.ts +99 -0
  47. package/templates/_base/apps/api/project.json +22 -0
  48. package/templates/_base/apps/api/schema.ts +11 -0
  49. package/templates/_base/apps/api/todos/crud.ts +81 -0
  50. package/templates/_base/apps/api/todos/schema.ts +11 -0
  51. package/templates/_base/apps/api/todos/types.ts +22 -0
  52. package/templates/_base/apps/api/tsconfig.json +23 -0
  53. package/templates/_base/apps/api/types.ts +16 -0
  54. package/templates/_base/biome.json +114 -0
  55. package/templates/_base/convex.json +4 -0
  56. package/templates/_base/emails/project.json +16 -0
  57. package/templates/_base/emails/tsconfig.json +5 -0
  58. package/templates/_base/emails/welcome_email.tsx +53 -0
  59. package/templates/_base/nx.json +29 -0
  60. package/templates/_base/package.json +73 -0
  61. package/templates/_base/scripts/sync_convex_env.ts +63 -0
  62. package/templates/_base/shared/assets/image.d.ts +4 -0
  63. package/templates/_base/shared/assets/src/styles/global.css +73 -0
  64. package/templates/_base/shared/assets/tsconfig.json +5 -0
  65. package/templates/_base/shared/ui/src/base/alert_dialog.tsx +139 -0
  66. package/templates/_base/shared/ui/src/base/badge.tsx +33 -0
  67. package/templates/_base/shared/ui/src/base/basic_data_table.tsx +61 -0
  68. package/templates/_base/shared/ui/src/base/button.tsx +69 -0
  69. package/templates/_base/shared/ui/src/base/button_group.tsx +82 -0
  70. package/templates/_base/shared/ui/src/base/card.tsx +79 -0
  71. package/templates/_base/shared/ui/src/base/checkbox.tsx +26 -0
  72. package/templates/_base/shared/ui/src/base/command.tsx +165 -0
  73. package/templates/_base/shared/ui/src/base/dialog.tsx +129 -0
  74. package/templates/_base/shared/ui/src/base/dropdown_menu.tsx +232 -0
  75. package/templates/_base/shared/ui/src/base/form.tsx +161 -0
  76. package/templates/_base/shared/ui/src/base/input.tsx +129 -0
  77. package/templates/_base/shared/ui/src/base/label.tsx +19 -0
  78. package/templates/_base/shared/ui/src/base/popover.tsx +46 -0
  79. package/templates/_base/shared/ui/src/base/radio_group.tsx +49 -0
  80. package/templates/_base/shared/ui/src/base/resizable.tsx +55 -0
  81. package/templates/_base/shared/ui/src/base/scroll_area.tsx +44 -0
  82. package/templates/_base/shared/ui/src/base/select.tsx +151 -0
  83. package/templates/_base/shared/ui/src/base/separator.tsx +32 -0
  84. package/templates/_base/shared/ui/src/base/sheet.tsx +130 -0
  85. package/templates/_base/shared/ui/src/base/side_bar.tsx +688 -0
  86. package/templates/_base/shared/ui/src/base/skeleton.tsx +7 -0
  87. package/templates/_base/shared/ui/src/base/spinner.tsx +20 -0
  88. package/templates/_base/shared/ui/src/base/switch.tsx +27 -0
  89. package/templates/_base/shared/ui/src/base/table.tsx +91 -0
  90. package/templates/_base/shared/ui/src/base/text_area.tsx +21 -0
  91. package/templates/_base/shared/ui/src/base/tooltip.tsx +31 -0
  92. package/templates/_base/shared/ui/src/base/utils.ts +17 -0
  93. package/templates/_base/shared/ui/src/hooks/use_keyboard_press.tsx +48 -0
  94. package/templates/_base/shared/ui/src/hooks/use_keyboard_release.tsx +48 -0
  95. package/templates/_base/shared/ui/src/hooks/use_mobile.tsx +25 -0
  96. package/templates/_base/shared/ui/src/hooks/use_mouse_click.tsx +44 -0
  97. package/templates/_base/shared/ui/src/hooks/use_mouse_location.tsx +55 -0
  98. package/templates/_base/shared/ui/src/hooks/use_outside_click.tsx +29 -0
  99. package/templates/_base/shared/ui/src/hooks/use_query_params.tsx +33 -0
  100. package/templates/_base/shared/ui/tsconfig.json +8 -0
  101. package/templates/_base/shared/utils/src/convex.ts +3 -0
  102. package/templates/_base/shared/utils/src/time.ts +12 -0
  103. package/templates/_base/shared/utils/tsconfig.json +5 -0
  104. package/templates/_base/skills-lock.json +35 -0
  105. package/templates/_base/tsconfig.base.json +34 -0
  106. package/templates/nextjs/.env.example +8 -0
  107. package/templates/nextjs/index.d.ts +6 -0
  108. package/templates/nextjs/next-env.d.ts +5 -0
  109. package/templates/nextjs/next.config.js +22 -0
  110. package/templates/nextjs/postcss.config.js +17 -0
  111. package/templates/nextjs/project.json +22 -0
  112. package/templates/nextjs/src/app/(auth)/layout.tsx +21 -0
  113. package/templates/nextjs/src/app/(auth)/not-allowed/page.tsx +22 -0
  114. package/templates/nextjs/src/app/(auth)/sign-in/[[...sign-in]]/page.tsx +15 -0
  115. package/templates/nextjs/src/app/(dashboard)/layout.tsx +27 -0
  116. package/templates/nextjs/src/app/(dashboard)/page.tsx +5 -0
  117. package/templates/nextjs/src/app/(dashboard)/todos/[id]/page.tsx +23 -0
  118. package/templates/nextjs/src/app/(dashboard)/todos/page.tsx +16 -0
  119. package/templates/nextjs/src/app/app.css +3 -0
  120. package/templates/nextjs/src/app/layout.tsx +26 -0
  121. package/templates/nextjs/src/convex.ts +11 -0
  122. package/templates/nextjs/src/middleware.ts +18 -0
  123. package/templates/nextjs/src/providers/convex_provider.tsx +44 -0
  124. package/templates/nextjs/src/surfaces/home_surface.tsx +22 -0
  125. package/templates/nextjs/src/surfaces/todos/all_todos_surface.tsx +97 -0
  126. package/templates/nextjs/src/surfaces/todos/create_todo_sheet.tsx +107 -0
  127. package/templates/nextjs/src/surfaces/todos/single_todo_surface.tsx +90 -0
  128. package/templates/nextjs/src/ui/sidebar/nav_link.tsx +36 -0
  129. package/templates/nextjs/src/ui/sidebar/sidebar.tsx +125 -0
  130. package/templates/nextjs/src/utils/font.ts +9 -0
  131. package/templates/nextjs/tsconfig.json +42 -0
  132. package/templates/react-router/.env.example +8 -0
  133. package/templates/react-router/postcss.config.js +15 -0
  134. package/templates/react-router/project.json +23 -0
  135. package/templates/react-router/public/favicon.ico +0 -0
  136. package/templates/react-router/react-router.config.ts +9 -0
  137. package/templates/react-router/src/app.css +3 -0
  138. package/templates/react-router/src/components/error_boundary.tsx +33 -0
  139. package/templates/react-router/src/layouts/sidebar/sidebar_aside/sidebar_aside.tsx +76 -0
  140. package/templates/react-router/src/layouts/sidebar/sidebar_aside/user_menu.tsx +36 -0
  141. package/templates/react-router/src/layouts/sidebar/sidebar_layout.tsx +22 -0
  142. package/templates/react-router/src/providers/api_auth_provider.tsx +38 -0
  143. package/templates/react-router/src/root.tsx +37 -0
  144. package/templates/react-router/src/routes/auth/layout.tsx +13 -0
  145. package/templates/react-router/src/routes/auth/sign-in.tsx +13 -0
  146. package/templates/react-router/src/routes/index.tsx +9 -0
  147. package/templates/react-router/src/routes/layout.tsx +26 -0
  148. package/templates/react-router/src/routes/todos/[id].tsx +22 -0
  149. package/templates/react-router/src/routes/todos/index.tsx +13 -0
  150. package/templates/react-router/src/routes.ts +12 -0
  151. package/templates/react-router/src/surfaces/home_surface.tsx +20 -0
  152. package/templates/react-router/src/surfaces/todos/all_todos_surface.tsx +87 -0
  153. package/templates/react-router/src/surfaces/todos/create_todo_sheet.tsx +102 -0
  154. package/templates/react-router/src/surfaces/todos/single_todo_surface.tsx +81 -0
  155. package/templates/react-router/tsconfig.json +20 -0
  156. package/templates/react-router/vite.config.ts +40 -0
@@ -0,0 +1,69 @@
1
+ import { Slot } from "@radix-ui/react-slot";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+ import { Loader2 } from "lucide-react";
4
+ import * as React from "react";
5
+
6
+ import { cn } from "@/ui/base/utils";
7
+
8
+ const buttonVariants = cva(
9
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-color_tool.tsx focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
10
+ {
11
+ variants: {
12
+ variant: {
13
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
14
+ destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
15
+ outline:
16
+ "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
17
+ secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
18
+ ghost: "hover:bg-accent hover:text-accent-foreground",
19
+ link: "text-primary underline-offset-4 hover:underline",
20
+ },
21
+ size: {
22
+ default: "h-9 px-4 py-2",
23
+ sm: "h-8 rounded-md px-3 text-xs",
24
+ lg: "h-10 rounded-md px-8",
25
+ icon: "h-9 w-9",
26
+ },
27
+ },
28
+ defaultVariants: {
29
+ variant: "default",
30
+ size: "default",
31
+ },
32
+ },
33
+ );
34
+
35
+ export interface ButtonProps
36
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
37
+ VariantProps<typeof buttonVariants> {
38
+ asChild?: boolean;
39
+ isLoading?: boolean;
40
+ }
41
+
42
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
43
+ ({ className, isLoading, variant, size, asChild = false, ...props }, ref) => {
44
+ const Comp = asChild ? Slot : "button";
45
+
46
+ if (isLoading) {
47
+ props.disabled = true;
48
+ return (
49
+ <button
50
+ type="button"
51
+ className={cn(buttonVariants({ variant, size, className }))}
52
+ ref={ref}
53
+ {...props}
54
+ >
55
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
56
+ <>{props.children}</>
57
+ </button>
58
+ );
59
+ }
60
+
61
+ return (
62
+ <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />
63
+ );
64
+ },
65
+ );
66
+
67
+ Button.displayName = "Button";
68
+
69
+ export { Button, buttonVariants };
@@ -0,0 +1,82 @@
1
+ /*
2
+ * Copyright (c) Aron Weston 2025.
3
+ */
4
+
5
+ import { Slot } from "@radix-ui/react-slot";
6
+ import { cva, type VariantProps } from "class-variance-authority";
7
+
8
+ import { Separator } from "@/ui/base/separator";
9
+ import { cn } from "@/ui/base/utils";
10
+
11
+ const buttonGroupVariants = cva(
12
+ "flex w-fit items-stretch [&>*]:focus-visible:z-10 [&>*]:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2",
13
+ {
14
+ variants: {
15
+ orientation: {
16
+ horizontal:
17
+ "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
18
+ vertical:
19
+ "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none",
20
+ },
21
+ },
22
+ defaultVariants: {
23
+ orientation: "horizontal",
24
+ },
25
+ },
26
+ );
27
+
28
+ function ButtonGroup({
29
+ className,
30
+ orientation,
31
+ ...props
32
+ }: React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>) {
33
+ return (
34
+ <div
35
+ role="group"
36
+ data-slot="button-group"
37
+ data-orientation={orientation}
38
+ className={cn(buttonGroupVariants({ orientation }), className)}
39
+ {...props}
40
+ />
41
+ );
42
+ }
43
+
44
+ function ButtonGroupText({
45
+ className,
46
+ asChild = false,
47
+ ...props
48
+ }: React.ComponentProps<"div"> & {
49
+ asChild?: boolean;
50
+ }) {
51
+ const Comp = asChild ? Slot : "div";
52
+
53
+ return (
54
+ <Comp
55
+ className={cn(
56
+ "bg-muted flex items-center gap-2 rounded-md border px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
57
+ className,
58
+ )}
59
+ {...props}
60
+ />
61
+ );
62
+ }
63
+
64
+ function ButtonGroupSeparator({
65
+ className,
66
+ orientation = "vertical",
67
+ ...props
68
+ }: React.ComponentProps<typeof Separator>) {
69
+ return (
70
+ <Separator
71
+ data-slot="button-group-separator"
72
+ orientation={orientation}
73
+ className={cn(
74
+ "bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto",
75
+ className,
76
+ )}
77
+ {...props}
78
+ />
79
+ );
80
+ }
81
+
82
+ export { ButtonGroup, ButtonGroupSeparator, ButtonGroupText, buttonGroupVariants };
@@ -0,0 +1,79 @@
1
+ /*
2
+ * Copyright (c) Aron Weston 2025.
3
+ */
4
+
5
+ import type * as React from "react";
6
+
7
+ import { cn } from "@/ui/base/utils";
8
+
9
+ function Card({ className, ...props }: React.ComponentProps<"div">) {
10
+ return (
11
+ <div
12
+ data-slot="card"
13
+ className={cn(
14
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border border-border py-6 shadow-sm",
15
+ className,
16
+ )}
17
+ {...props}
18
+ />
19
+ );
20
+ }
21
+
22
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
23
+ return (
24
+ <div
25
+ data-slot="card-header"
26
+ className={cn(
27
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
28
+ className,
29
+ )}
30
+ {...props}
31
+ />
32
+ );
33
+ }
34
+
35
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
36
+ return (
37
+ <div
38
+ data-slot="card-title"
39
+ className={cn("leading-none font-semibold", className)}
40
+ {...props}
41
+ />
42
+ );
43
+ }
44
+
45
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
46
+ return (
47
+ <div
48
+ data-slot="card-description"
49
+ className={cn("text-muted-foreground text-sm", className)}
50
+ {...props}
51
+ />
52
+ );
53
+ }
54
+
55
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
56
+ return (
57
+ <div
58
+ data-slot="card-action"
59
+ className={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)}
60
+ {...props}
61
+ />
62
+ );
63
+ }
64
+
65
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
66
+ return <div data-slot="card-content" className={cn("px-6", className)} {...props} />;
67
+ }
68
+
69
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
70
+ return (
71
+ <div
72
+ data-slot="card-footer"
73
+ className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
74
+ {...props}
75
+ />
76
+ );
77
+ }
78
+
79
+ export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
@@ -0,0 +1,26 @@
1
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
2
+ import { Check } from "lucide-react";
3
+ import * as React from "react";
4
+
5
+ import { cn } from "@/ui/base/utils";
6
+
7
+ const Checkbox = React.forwardRef<
8
+ React.ElementRef<typeof CheckboxPrimitive.Root>,
9
+ React.ComponentPropsWithoutRef<typeof CheckboxPrimitive.Root>
10
+ >(({ className, ...props }, ref) => (
11
+ <CheckboxPrimitive.Root
12
+ ref={ref}
13
+ className={cn(
14
+ "peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
15
+ className,
16
+ )}
17
+ {...props}
18
+ >
19
+ <CheckboxPrimitive.Indicator className={cn("flex items-center justify-center text-current")}>
20
+ <Check className="h-4 w-4" />
21
+ </CheckboxPrimitive.Indicator>
22
+ </CheckboxPrimitive.Root>
23
+ ));
24
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName;
25
+
26
+ export { Checkbox };
@@ -0,0 +1,165 @@
1
+ /*
2
+ * Copyright (c) Aron Weston 2025.
3
+ */
4
+
5
+ "use client";
6
+
7
+ import { Command as CommandPrimitive } from "cmdk";
8
+ import { SearchIcon } from "lucide-react";
9
+ import type * as React from "react";
10
+
11
+ import {
12
+ Dialog,
13
+ DialogContent,
14
+ DialogDescription,
15
+ DialogHeader,
16
+ DialogTitle,
17
+ } from "@/ui/base/dialog";
18
+ import { cn } from "@/ui/base/utils";
19
+
20
+ function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {
21
+ return (
22
+ <CommandPrimitive
23
+ data-slot="command"
24
+ className={cn(
25
+ "bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
26
+ className,
27
+ )}
28
+ {...props}
29
+ />
30
+ );
31
+ }
32
+
33
+ function CommandDialog({
34
+ title = "Command Palette",
35
+ description = "Search for a command to run...",
36
+ children,
37
+ className,
38
+ showCloseButton = true,
39
+ ...props
40
+ }: React.ComponentProps<typeof Dialog> & {
41
+ title?: string;
42
+ description?: string;
43
+ className?: string;
44
+ showCloseButton?: boolean;
45
+ }) {
46
+ return (
47
+ <Dialog {...props}>
48
+ <DialogHeader className="sr-only">
49
+ <DialogTitle>{title}</DialogTitle>
50
+ <DialogDescription>{description}</DialogDescription>
51
+ </DialogHeader>
52
+ <DialogContent
53
+ className={cn("overflow-hidden p-0", className)}
54
+ showCloseButton={showCloseButton}
55
+ >
56
+ <Command className="[&_[cmdk-group-heading]]:text-muted-foreground **:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
57
+ {children}
58
+ </Command>
59
+ </DialogContent>
60
+ </Dialog>
61
+ );
62
+ }
63
+
64
+ function CommandInput({
65
+ className,
66
+ ...props
67
+ }: React.ComponentProps<typeof CommandPrimitive.Input>) {
68
+ return (
69
+ <div data-slot="command-input-wrapper" className="flex h-9 items-center gap-2 border-b px-3">
70
+ <SearchIcon className="size-4 shrink-0 opacity-50" />
71
+ <CommandPrimitive.Input
72
+ data-slot="command-input"
73
+ className={cn(
74
+ "placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50",
75
+ className,
76
+ )}
77
+ {...props}
78
+ />
79
+ </div>
80
+ );
81
+ }
82
+
83
+ function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
84
+ return (
85
+ <CommandPrimitive.List
86
+ data-slot="command-list"
87
+ className={cn("max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto", className)}
88
+ {...props}
89
+ />
90
+ );
91
+ }
92
+
93
+ function CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {
94
+ return (
95
+ <CommandPrimitive.Empty
96
+ data-slot="command-empty"
97
+ className="py-6 text-center text-sm"
98
+ {...props}
99
+ />
100
+ );
101
+ }
102
+
103
+ function CommandGroup({
104
+ className,
105
+ ...props
106
+ }: React.ComponentProps<typeof CommandPrimitive.Group>) {
107
+ return (
108
+ <CommandPrimitive.Group
109
+ data-slot="command-group"
110
+ className={cn(
111
+ "text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
112
+ className,
113
+ )}
114
+ {...props}
115
+ />
116
+ );
117
+ }
118
+
119
+ function CommandSeparator({
120
+ className,
121
+ ...props
122
+ }: React.ComponentProps<typeof CommandPrimitive.Separator>) {
123
+ return (
124
+ <CommandPrimitive.Separator
125
+ data-slot="command-separator"
126
+ className={cn("bg-border -mx-1 h-px", className)}
127
+ {...props}
128
+ />
129
+ );
130
+ }
131
+
132
+ function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {
133
+ return (
134
+ <CommandPrimitive.Item
135
+ data-slot="command-item"
136
+ className={cn(
137
+ "data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
138
+ className,
139
+ )}
140
+ {...props}
141
+ />
142
+ );
143
+ }
144
+
145
+ function CommandShortcut({ className, ...props }: React.ComponentProps<"span">) {
146
+ return (
147
+ <span
148
+ data-slot="command-shortcut"
149
+ className={cn("text-muted-foreground ml-auto text-xs tracking-widest", className)}
150
+ {...props}
151
+ />
152
+ );
153
+ }
154
+
155
+ export {
156
+ Command,
157
+ CommandDialog,
158
+ CommandInput,
159
+ CommandList,
160
+ CommandEmpty,
161
+ CommandGroup,
162
+ CommandItem,
163
+ CommandShortcut,
164
+ CommandSeparator,
165
+ };
@@ -0,0 +1,129 @@
1
+ "use client";
2
+
3
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
4
+ import { XIcon } from "lucide-react";
5
+ import type * as React from "react";
6
+
7
+ import { cn } from "@/ui/base/utils";
8
+
9
+ function Dialog({ ...props }: React.ComponentProps<typeof DialogPrimitive.Root>) {
10
+ return <DialogPrimitive.Root data-slot="dialog" {...props} />;
11
+ }
12
+
13
+ function DialogTrigger({ ...props }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
14
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
15
+ }
16
+
17
+ function DialogPortal({ ...props }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
18
+ return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
19
+ }
20
+
21
+ function DialogClose({ ...props }: React.ComponentProps<typeof DialogPrimitive.Close>) {
22
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
23
+ }
24
+
25
+ function DialogOverlay({
26
+ className,
27
+ ...props
28
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
29
+ return (
30
+ <DialogPrimitive.Overlay
31
+ data-slot="dialog-overlay"
32
+ className={cn(
33
+ "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-white/50 backdrop-blur-md",
34
+ className,
35
+ )}
36
+ {...props}
37
+ />
38
+ );
39
+ }
40
+
41
+ function DialogContent({
42
+ className,
43
+ children,
44
+ showCloseButton = true,
45
+ ...props
46
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
47
+ showCloseButton?: boolean;
48
+ }) {
49
+ return (
50
+ <DialogPortal data-slot="dialog-portal">
51
+ <DialogOverlay />
52
+ <DialogPrimitive.Content
53
+ data-slot="dialog-content"
54
+ className={cn(
55
+ "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 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 p-6 shadow-lg duration-200 sm:max-w-lg",
56
+ className,
57
+ )}
58
+ {...props}
59
+ >
60
+ {children}
61
+ {showCloseButton && (
62
+ <DialogPrimitive.Close
63
+ data-slot="dialog-close"
64
+ className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
65
+ >
66
+ <XIcon />
67
+ <span className="sr-only">Close</span>
68
+ </DialogPrimitive.Close>
69
+ )}
70
+ </DialogPrimitive.Content>
71
+ </DialogPortal>
72
+ );
73
+ }
74
+
75
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
76
+ return (
77
+ <div
78
+ data-slot="dialog-header"
79
+ className={cn("flex flex-col gap-2 text-center sm:text-left", className)}
80
+ {...props}
81
+ />
82
+ );
83
+ }
84
+
85
+ function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
86
+ return (
87
+ <div
88
+ data-slot="dialog-footer"
89
+ className={cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className)}
90
+ {...props}
91
+ />
92
+ );
93
+ }
94
+
95
+ function DialogTitle({ className, ...props }: React.ComponentProps<typeof DialogPrimitive.Title>) {
96
+ return (
97
+ <DialogPrimitive.Title
98
+ data-slot="dialog-title"
99
+ className={cn("text-lg leading-none font-semibold", className)}
100
+ {...props}
101
+ />
102
+ );
103
+ }
104
+
105
+ function DialogDescription({
106
+ className,
107
+ ...props
108
+ }: React.ComponentProps<typeof DialogPrimitive.Description>) {
109
+ return (
110
+ <DialogPrimitive.Description
111
+ data-slot="dialog-description"
112
+ className={cn("text-muted-foreground text-sm", className)}
113
+ {...props}
114
+ />
115
+ );
116
+ }
117
+
118
+ export {
119
+ Dialog,
120
+ DialogClose,
121
+ DialogContent,
122
+ DialogDescription,
123
+ DialogFooter,
124
+ DialogHeader,
125
+ DialogOverlay,
126
+ DialogPortal,
127
+ DialogTitle,
128
+ DialogTrigger,
129
+ };