@kidecms/core 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/README.md +28 -0
- package/admin/components/AdminCard.astro +25 -0
- package/admin/components/AiGenerateButton.tsx +102 -0
- package/admin/components/AssetsGrid.tsx +711 -0
- package/admin/components/BlockEditor.tsx +996 -0
- package/admin/components/CheckboxField.tsx +31 -0
- package/admin/components/DocumentActions.tsx +317 -0
- package/admin/components/DocumentLock.tsx +54 -0
- package/admin/components/DocumentsDataTable.tsx +804 -0
- package/admin/components/FieldControl.astro +397 -0
- package/admin/components/FocalPointSelector.tsx +100 -0
- package/admin/components/ImageBrowseDialog.tsx +176 -0
- package/admin/components/ImagePicker.tsx +149 -0
- package/admin/components/InternalLinkPicker.tsx +80 -0
- package/admin/components/LiveHeading.tsx +17 -0
- package/admin/components/MobileSidebar.tsx +29 -0
- package/admin/components/RelationField.tsx +204 -0
- package/admin/components/RichTextEditor.tsx +685 -0
- package/admin/components/SelectField.tsx +65 -0
- package/admin/components/SidebarUserMenu.tsx +99 -0
- package/admin/components/SlugField.tsx +77 -0
- package/admin/components/TaxonomySelect.tsx +52 -0
- package/admin/components/Toast.astro +40 -0
- package/admin/components/TreeItemsEditor.tsx +790 -0
- package/admin/components/TreeSelect.tsx +166 -0
- package/admin/components/UnsavedGuard.tsx +181 -0
- package/admin/components/tree-utils.ts +86 -0
- package/admin/components/ui/alert-dialog.tsx +92 -0
- package/admin/components/ui/badge.tsx +83 -0
- package/admin/components/ui/button.tsx +53 -0
- package/admin/components/ui/card.tsx +70 -0
- package/admin/components/ui/checkbox.tsx +28 -0
- package/admin/components/ui/collapsible.tsx +26 -0
- package/admin/components/ui/command.tsx +88 -0
- package/admin/components/ui/dialog.tsx +92 -0
- package/admin/components/ui/dropdown-menu.tsx +259 -0
- package/admin/components/ui/input.tsx +20 -0
- package/admin/components/ui/label.tsx +20 -0
- package/admin/components/ui/popover.tsx +42 -0
- package/admin/components/ui/select.tsx +165 -0
- package/admin/components/ui/separator.tsx +21 -0
- package/admin/components/ui/sheet.tsx +104 -0
- package/admin/components/ui/skeleton.tsx +7 -0
- package/admin/components/ui/table.tsx +74 -0
- package/admin/components/ui/textarea.tsx +18 -0
- package/admin/components/ui/tooltip.tsx +52 -0
- package/admin/layouts/AdminLayout.astro +340 -0
- package/admin/lib/utils.ts +19 -0
- package/dist/admin.js +92 -0
- package/dist/ai.js +67 -0
- package/dist/api.js +827 -0
- package/dist/assets.js +163 -0
- package/dist/auth.js +132 -0
- package/dist/blocks.js +110 -0
- package/dist/content.js +29 -0
- package/dist/create-admin.js +23 -0
- package/dist/define.js +36 -0
- package/dist/generator.js +370 -0
- package/dist/image.js +69 -0
- package/dist/index.js +16 -0
- package/dist/integration.js +256 -0
- package/dist/locks.js +37 -0
- package/dist/richtext.js +1 -0
- package/dist/runtime.js +26 -0
- package/dist/schema.js +13 -0
- package/dist/seed.js +84 -0
- package/dist/values.js +102 -0
- package/middleware/auth.ts +100 -0
- package/package.json +102 -0
- package/routes/api/cms/[collection]/[...path].ts +366 -0
- package/routes/api/cms/ai/alt-text.ts +25 -0
- package/routes/api/cms/ai/seo.ts +25 -0
- package/routes/api/cms/ai/translate.ts +31 -0
- package/routes/api/cms/assets/[id].ts +82 -0
- package/routes/api/cms/assets/folders.ts +81 -0
- package/routes/api/cms/assets/index.ts +23 -0
- package/routes/api/cms/assets/upload.ts +112 -0
- package/routes/api/cms/auth/invite.ts +166 -0
- package/routes/api/cms/auth/login.ts +124 -0
- package/routes/api/cms/auth/logout.ts +33 -0
- package/routes/api/cms/auth/setup.ts +77 -0
- package/routes/api/cms/cron/publish.ts +33 -0
- package/routes/api/cms/img/[...path].ts +24 -0
- package/routes/api/cms/locks/[...path].ts +37 -0
- package/routes/api/cms/preview/render.ts +36 -0
- package/routes/api/cms/references/[collection]/[id].ts +60 -0
- package/routes/pages/admin/[...path].astro +1104 -0
- package/routes/pages/admin/assets/[id].astro +183 -0
- package/routes/pages/admin/assets/index.astro +58 -0
- package/routes/pages/admin/invite.astro +116 -0
- package/routes/pages/admin/login.astro +57 -0
- package/routes/pages/admin/setup.astro +91 -0
- package/virtual.d.ts +61 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
function Card({ className, size = "default", ...props }: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
|
|
6
|
+
return (
|
|
7
|
+
<div
|
|
8
|
+
data-slot="card"
|
|
9
|
+
data-size={size}
|
|
10
|
+
className={cn(
|
|
11
|
+
"group/card bg-card text-card-foreground ring-foreground/10 flex flex-col gap-4 rounded-xl py-4 text-sm ring-1 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
|
|
12
|
+
className,
|
|
13
|
+
)}
|
|
14
|
+
{...props}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
20
|
+
return (
|
|
21
|
+
<div
|
|
22
|
+
data-slot="card-header"
|
|
23
|
+
className={cn(
|
|
24
|
+
"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",
|
|
25
|
+
className,
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
data-slot="card-title"
|
|
36
|
+
className={cn("text-base leading-snug font-medium group-data-[size=sm]/card:text-sm", className)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
|
|
43
|
+
return <div data-slot="card-description" className={cn("text-muted-foreground text-sm", className)} {...props} />;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function CardAction({ className, ...props }: React.ComponentProps<"div">) {
|
|
47
|
+
return (
|
|
48
|
+
<div
|
|
49
|
+
data-slot="card-action"
|
|
50
|
+
className={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function CardContent({ className, ...props }: React.ComponentProps<"div">) {
|
|
57
|
+
return <div data-slot="card-content" className={cn("px-4 group-data-[size=sm]/card:px-3", className)} {...props} />;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
61
|
+
return (
|
|
62
|
+
<div
|
|
63
|
+
data-slot="card-footer"
|
|
64
|
+
className={cn("bg-muted/50 flex items-center rounded-b-xl border-t p-4 group-data-[size=sm]/card:p-3", className)}
|
|
65
|
+
{...props}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardAction, CardDescription, CardContent };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
import { CheckIcon } from "lucide-react";
|
|
7
|
+
|
|
8
|
+
function Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {
|
|
9
|
+
return (
|
|
10
|
+
<CheckboxPrimitive.Root
|
|
11
|
+
data-slot="checkbox"
|
|
12
|
+
className={cn(
|
|
13
|
+
"peer border-input hover:border-primary/60 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:hover:border-primary/60 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary disabled:hover:border-input relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
>
|
|
18
|
+
<CheckboxPrimitive.Indicator
|
|
19
|
+
data-slot="checkbox-indicator"
|
|
20
|
+
className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
|
|
21
|
+
>
|
|
22
|
+
<CheckIcon />
|
|
23
|
+
</CheckboxPrimitive.Indicator>
|
|
24
|
+
</CheckboxPrimitive.Root>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { Checkbox };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Collapsible as CollapsiblePrimitive } from "@base-ui/react/collapsible";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
|
|
8
|
+
function Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {
|
|
9
|
+
return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {
|
|
13
|
+
return <CollapsiblePrimitive.Trigger data-slot="collapsible-trigger" {...props} />;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function CollapsibleContent({ className, ...props }: CollapsiblePrimitive.Panel.Props) {
|
|
17
|
+
return (
|
|
18
|
+
<CollapsiblePrimitive.Panel
|
|
19
|
+
data-slot="collapsible-content"
|
|
20
|
+
className={cn("overflow-hidden", className)}
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { Collapsible, CollapsibleTrigger, CollapsibleContent };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Command as CommandPrimitive } from "cmdk";
|
|
5
|
+
import { Search } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
import { cn } from "../../lib/utils";
|
|
8
|
+
|
|
9
|
+
function Command({ className, ...props }: React.ComponentProps<typeof CommandPrimitive>) {
|
|
10
|
+
return (
|
|
11
|
+
<CommandPrimitive
|
|
12
|
+
data-slot="command"
|
|
13
|
+
className={cn(
|
|
14
|
+
"bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
|
|
15
|
+
className,
|
|
16
|
+
)}
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function CommandInput({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Input>) {
|
|
23
|
+
return (
|
|
24
|
+
<div className="flex items-center border-b px-3" data-slot="command-input-wrapper">
|
|
25
|
+
<Search className="mr-2 size-4 shrink-0 opacity-50" />
|
|
26
|
+
<CommandPrimitive.Input
|
|
27
|
+
data-slot="command-input"
|
|
28
|
+
className={cn(
|
|
29
|
+
"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",
|
|
30
|
+
className,
|
|
31
|
+
)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {
|
|
39
|
+
return (
|
|
40
|
+
<CommandPrimitive.List
|
|
41
|
+
data-slot="command-list"
|
|
42
|
+
className={cn("max-h-[300px] overflow-x-hidden overflow-y-auto", className)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function CommandEmpty({ ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {
|
|
49
|
+
return <CommandPrimitive.Empty data-slot="command-empty" className="py-6 text-center text-sm" {...props} />;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {
|
|
53
|
+
return (
|
|
54
|
+
<CommandPrimitive.Group
|
|
55
|
+
data-slot="command-group"
|
|
56
|
+
className={cn(
|
|
57
|
+
"text-foreground [&_[cmdk-group-heading]]:bg-muted/50 [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:sticky [&_[cmdk-group-heading]]:top-0 [&_[cmdk-group-heading]]:px-3 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium",
|
|
58
|
+
className,
|
|
59
|
+
)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {
|
|
66
|
+
return (
|
|
67
|
+
<CommandPrimitive.Separator
|
|
68
|
+
data-slot="command-separator"
|
|
69
|
+
className={cn("bg-border -mx-1 h-px", className)}
|
|
70
|
+
{...props}
|
|
71
|
+
/>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function CommandItem({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Item>) {
|
|
76
|
+
return (
|
|
77
|
+
<CommandPrimitive.Item
|
|
78
|
+
data-slot="command-item"
|
|
79
|
+
className={cn(
|
|
80
|
+
"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm 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]:size-4 [&_svg]:shrink-0",
|
|
81
|
+
className,
|
|
82
|
+
)}
|
|
83
|
+
{...props}
|
|
84
|
+
/>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandSeparator, CommandItem };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Dialog as DialogPrimitive } from "@base-ui/react/dialog";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
|
|
8
|
+
function Dialog({ ...props }: DialogPrimitive.Root.Props) {
|
|
9
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
|
|
13
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
|
|
17
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function DialogOverlay({ className, ...props }: DialogPrimitive.Backdrop.Props) {
|
|
21
|
+
return (
|
|
22
|
+
<DialogPrimitive.Backdrop
|
|
23
|
+
data-slot="dialog-overlay"
|
|
24
|
+
className={cn(
|
|
25
|
+
"fixed inset-0 z-50 bg-black/50 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0",
|
|
26
|
+
className,
|
|
27
|
+
)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function DialogContent({ className, children, ...props }: DialogPrimitive.Popup.Props) {
|
|
34
|
+
return (
|
|
35
|
+
<DialogPortal>
|
|
36
|
+
<DialogOverlay />
|
|
37
|
+
<DialogPrimitive.Popup
|
|
38
|
+
data-slot="dialog-content"
|
|
39
|
+
className={cn(
|
|
40
|
+
"bg-background fixed top-1/2 left-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-lg border p-6 shadow-lg transition duration-150 data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0",
|
|
41
|
+
className,
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
>
|
|
45
|
+
{children}
|
|
46
|
+
</DialogPrimitive.Popup>
|
|
47
|
+
</DialogPortal>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
52
|
+
return <div data-slot="dialog-header" className={cn("flex flex-col gap-1", className)} {...props} />;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
56
|
+
return <div data-slot="dialog-footer" className={cn("flex justify-end gap-2", className)} {...props} />;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
|
|
60
|
+
return (
|
|
61
|
+
<DialogPrimitive.Title
|
|
62
|
+
data-slot="dialog-title"
|
|
63
|
+
className={cn("text-foreground text-base font-semibold", className)}
|
|
64
|
+
{...props}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function DialogDescription({ className, ...props }: DialogPrimitive.Description.Props) {
|
|
70
|
+
return (
|
|
71
|
+
<DialogPrimitive.Description
|
|
72
|
+
data-slot="dialog-description"
|
|
73
|
+
className={cn("text-muted-foreground text-sm", className)}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
|
|
80
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export {
|
|
84
|
+
Dialog,
|
|
85
|
+
DialogTrigger,
|
|
86
|
+
DialogContent,
|
|
87
|
+
DialogHeader,
|
|
88
|
+
DialogFooter,
|
|
89
|
+
DialogTitle,
|
|
90
|
+
DialogDescription,
|
|
91
|
+
DialogClose,
|
|
92
|
+
};
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
import { ChevronRightIcon, CheckIcon } from "lucide-react";
|
|
8
|
+
|
|
9
|
+
function DropdownMenu({ ...props }: DropdownMenuPrimitive.DropdownMenuProps) {
|
|
10
|
+
return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function DropdownMenuPortal({ ...props }: DropdownMenuPrimitive.DropdownMenuPortalProps) {
|
|
14
|
+
return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function DropdownMenuTrigger({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {
|
|
18
|
+
return (
|
|
19
|
+
<DropdownMenuPrimitive.Trigger
|
|
20
|
+
data-slot="dropdown-menu-trigger"
|
|
21
|
+
className={cn("outline-none", className)}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function DropdownMenuContent({
|
|
28
|
+
align = "start",
|
|
29
|
+
alignOffset = 0,
|
|
30
|
+
side = "bottom",
|
|
31
|
+
sideOffset = 4,
|
|
32
|
+
className,
|
|
33
|
+
...props
|
|
34
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {
|
|
35
|
+
return (
|
|
36
|
+
<DropdownMenuPrimitive.Portal>
|
|
37
|
+
<DropdownMenuPrimitive.Content
|
|
38
|
+
data-slot="dropdown-menu-content"
|
|
39
|
+
align={align}
|
|
40
|
+
alignOffset={alignOffset}
|
|
41
|
+
side={side}
|
|
42
|
+
sideOffset={sideOffset}
|
|
43
|
+
className={cn(
|
|
44
|
+
"bg-popover text-popover-foreground ring-foreground/10 z-50 max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-32 overflow-x-hidden overflow-y-auto rounded-lg p-1 shadow-md ring-1 outline-none",
|
|
45
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
46
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
47
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
48
|
+
className,
|
|
49
|
+
)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
</DropdownMenuPrimitive.Portal>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {
|
|
57
|
+
return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function DropdownMenuLabel({
|
|
61
|
+
className,
|
|
62
|
+
inset,
|
|
63
|
+
...props
|
|
64
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {
|
|
65
|
+
inset?: boolean;
|
|
66
|
+
}) {
|
|
67
|
+
return (
|
|
68
|
+
<DropdownMenuPrimitive.Label
|
|
69
|
+
data-slot="dropdown-menu-label"
|
|
70
|
+
data-inset={inset}
|
|
71
|
+
className={cn("text-muted-foreground px-1.5 py-1 text-xs font-medium data-[inset]:pl-7", className)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function DropdownMenuItem({
|
|
78
|
+
className,
|
|
79
|
+
inset,
|
|
80
|
+
variant = "default",
|
|
81
|
+
...props
|
|
82
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {
|
|
83
|
+
inset?: boolean;
|
|
84
|
+
variant?: "default" | "destructive";
|
|
85
|
+
}) {
|
|
86
|
+
return (
|
|
87
|
+
<DropdownMenuPrimitive.Item
|
|
88
|
+
data-slot="dropdown-menu-item"
|
|
89
|
+
data-inset={inset}
|
|
90
|
+
data-variant={variant}
|
|
91
|
+
className={cn(
|
|
92
|
+
"group/dropdown-menu-item focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
93
|
+
variant === "destructive" &&
|
|
94
|
+
"text-destructive focus:bg-destructive/10 focus:text-destructive dark:focus:bg-destructive/20 *:[svg]:text-destructive",
|
|
95
|
+
variant === "default" && "focus:**:text-accent-foreground",
|
|
96
|
+
className,
|
|
97
|
+
)}
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function DropdownMenuSub({ ...props }: DropdownMenuPrimitive.DropdownMenuSubProps) {
|
|
104
|
+
return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function DropdownMenuSubTrigger({
|
|
108
|
+
className,
|
|
109
|
+
inset,
|
|
110
|
+
children,
|
|
111
|
+
...props
|
|
112
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {
|
|
113
|
+
inset?: boolean;
|
|
114
|
+
}) {
|
|
115
|
+
return (
|
|
116
|
+
<DropdownMenuPrimitive.SubTrigger
|
|
117
|
+
data-slot="dropdown-menu-sub-trigger"
|
|
118
|
+
data-inset={inset}
|
|
119
|
+
className={cn(
|
|
120
|
+
"focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none data-[inset]:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
121
|
+
className,
|
|
122
|
+
)}
|
|
123
|
+
{...props}
|
|
124
|
+
>
|
|
125
|
+
{children}
|
|
126
|
+
<ChevronRightIcon className="ml-auto" />
|
|
127
|
+
</DropdownMenuPrimitive.SubTrigger>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function DropdownMenuSubContent({
|
|
132
|
+
className,
|
|
133
|
+
...props
|
|
134
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {
|
|
135
|
+
return (
|
|
136
|
+
<DropdownMenuPrimitive.Portal>
|
|
137
|
+
<DropdownMenuPrimitive.SubContent
|
|
138
|
+
data-slot="dropdown-menu-sub-content"
|
|
139
|
+
className={cn(
|
|
140
|
+
"bg-popover text-popover-foreground ring-foreground/10 z-50 min-w-24 overflow-hidden rounded-lg p-1 shadow-lg ring-1",
|
|
141
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
142
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
143
|
+
"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
144
|
+
className,
|
|
145
|
+
)}
|
|
146
|
+
{...props}
|
|
147
|
+
/>
|
|
148
|
+
</DropdownMenuPrimitive.Portal>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function DropdownMenuCheckboxItem({
|
|
153
|
+
className,
|
|
154
|
+
children,
|
|
155
|
+
checked,
|
|
156
|
+
inset,
|
|
157
|
+
...props
|
|
158
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {
|
|
159
|
+
inset?: boolean;
|
|
160
|
+
}) {
|
|
161
|
+
return (
|
|
162
|
+
<DropdownMenuPrimitive.CheckboxItem
|
|
163
|
+
data-slot="dropdown-menu-checkbox-item"
|
|
164
|
+
data-inset={inset}
|
|
165
|
+
className={cn(
|
|
166
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
167
|
+
className,
|
|
168
|
+
)}
|
|
169
|
+
checked={checked}
|
|
170
|
+
{...props}
|
|
171
|
+
>
|
|
172
|
+
<span
|
|
173
|
+
className="pointer-events-none absolute right-2 flex items-center justify-center"
|
|
174
|
+
data-slot="dropdown-menu-checkbox-item-indicator"
|
|
175
|
+
>
|
|
176
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
177
|
+
<CheckIcon />
|
|
178
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
179
|
+
</span>
|
|
180
|
+
{children}
|
|
181
|
+
</DropdownMenuPrimitive.CheckboxItem>
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function DropdownMenuRadioGroup({ ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {
|
|
186
|
+
return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function DropdownMenuRadioItem({
|
|
190
|
+
className,
|
|
191
|
+
children,
|
|
192
|
+
inset,
|
|
193
|
+
...props
|
|
194
|
+
}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {
|
|
195
|
+
inset?: boolean;
|
|
196
|
+
}) {
|
|
197
|
+
return (
|
|
198
|
+
<DropdownMenuPrimitive.RadioItem
|
|
199
|
+
data-slot="dropdown-menu-radio-item"
|
|
200
|
+
data-inset={inset}
|
|
201
|
+
className={cn(
|
|
202
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-7 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
203
|
+
className,
|
|
204
|
+
)}
|
|
205
|
+
{...props}
|
|
206
|
+
>
|
|
207
|
+
<span
|
|
208
|
+
className="pointer-events-none absolute right-2 flex items-center justify-center"
|
|
209
|
+
data-slot="dropdown-menu-radio-item-indicator"
|
|
210
|
+
>
|
|
211
|
+
<DropdownMenuPrimitive.ItemIndicator>
|
|
212
|
+
<CheckIcon />
|
|
213
|
+
</DropdownMenuPrimitive.ItemIndicator>
|
|
214
|
+
</span>
|
|
215
|
+
{children}
|
|
216
|
+
</DropdownMenuPrimitive.RadioItem>
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function DropdownMenuSeparator({ className, ...props }: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {
|
|
221
|
+
return (
|
|
222
|
+
<DropdownMenuPrimitive.Separator
|
|
223
|
+
data-slot="dropdown-menu-separator"
|
|
224
|
+
className={cn("bg-border -mx-1 my-1 h-px", className)}
|
|
225
|
+
{...props}
|
|
226
|
+
/>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<"span">) {
|
|
231
|
+
return (
|
|
232
|
+
<span
|
|
233
|
+
data-slot="dropdown-menu-shortcut"
|
|
234
|
+
className={cn(
|
|
235
|
+
"text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground ml-auto text-xs tracking-widest",
|
|
236
|
+
className,
|
|
237
|
+
)}
|
|
238
|
+
{...props}
|
|
239
|
+
/>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export {
|
|
244
|
+
DropdownMenu,
|
|
245
|
+
DropdownMenuPortal,
|
|
246
|
+
DropdownMenuTrigger,
|
|
247
|
+
DropdownMenuContent,
|
|
248
|
+
DropdownMenuGroup,
|
|
249
|
+
DropdownMenuLabel,
|
|
250
|
+
DropdownMenuItem,
|
|
251
|
+
DropdownMenuCheckboxItem,
|
|
252
|
+
DropdownMenuRadioGroup,
|
|
253
|
+
DropdownMenuRadioItem,
|
|
254
|
+
DropdownMenuSeparator,
|
|
255
|
+
DropdownMenuShortcut,
|
|
256
|
+
DropdownMenuSub,
|
|
257
|
+
DropdownMenuSubTrigger,
|
|
258
|
+
DropdownMenuSubContent,
|
|
259
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Input as InputPrimitive } from "@base-ui/react/input";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils";
|
|
5
|
+
|
|
6
|
+
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
|
7
|
+
return (
|
|
8
|
+
<InputPrimitive
|
|
9
|
+
type={type}
|
|
10
|
+
data-slot="input"
|
|
11
|
+
className={cn(
|
|
12
|
+
"border-input hover:border-foreground/20 file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 disabled:bg-input/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 bg-muted/30 read-only:hover:border-input read-only:focus-visible:border-input read-only:text-muted-foreground h-9 w-full min-w-0 rounded-lg border px-3 py-1.5 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:font-medium read-only:cursor-not-allowed focus-visible:ring-3 read-only:focus-visible:ring-0 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3",
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { Input };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
|
|
7
|
+
function Label({ className, ...props }: React.ComponentProps<"label">) {
|
|
8
|
+
return (
|
|
9
|
+
<label
|
|
10
|
+
data-slot="label"
|
|
11
|
+
className={cn(
|
|
12
|
+
"text-foreground/80 flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { Label };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
|
|
8
|
+
function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
|
9
|
+
return <PopoverPrimitive.Root data-slot="popover" {...props} />;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
|
13
|
+
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function PopoverContent({
|
|
17
|
+
className,
|
|
18
|
+
align = "center",
|
|
19
|
+
sideOffset = 4,
|
|
20
|
+
...props
|
|
21
|
+
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
|
22
|
+
return (
|
|
23
|
+
<PopoverPrimitive.Portal>
|
|
24
|
+
<PopoverPrimitive.Content
|
|
25
|
+
data-slot="popover-content"
|
|
26
|
+
align={align}
|
|
27
|
+
sideOffset={sideOffset}
|
|
28
|
+
className={cn(
|
|
29
|
+
"bg-popover text-popover-foreground 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 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
|
|
30
|
+
className,
|
|
31
|
+
)}
|
|
32
|
+
{...props}
|
|
33
|
+
/>
|
|
34
|
+
</PopoverPrimitive.Portal>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
|
|
39
|
+
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
|