@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,165 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Select as SelectPrimitive } from "@base-ui/react/select";
|
|
3
|
+
|
|
4
|
+
import { cn } from "../../lib/utils";
|
|
5
|
+
import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react";
|
|
6
|
+
|
|
7
|
+
const Select = SelectPrimitive.Root;
|
|
8
|
+
|
|
9
|
+
function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
|
|
10
|
+
return <SelectPrimitive.Group data-slot="select-group" className={cn("scroll-my-1 p-1", className)} {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
|
|
14
|
+
return (
|
|
15
|
+
<SelectPrimitive.Value data-slot="select-value" className={cn("flex flex-1 text-left", className)} {...props} />
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function SelectTrigger({
|
|
20
|
+
className,
|
|
21
|
+
size = "default",
|
|
22
|
+
children,
|
|
23
|
+
...props
|
|
24
|
+
}: SelectPrimitive.Trigger.Props & {
|
|
25
|
+
size?: "sm" | "default";
|
|
26
|
+
}) {
|
|
27
|
+
return (
|
|
28
|
+
<SelectPrimitive.Trigger
|
|
29
|
+
data-slot="select-trigger"
|
|
30
|
+
data-size={size}
|
|
31
|
+
className={cn(
|
|
32
|
+
"border-input hover:bg-muted focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 bg-muted/30 flex w-fit items-center justify-between gap-1.5 rounded-lg border py-1.5 pr-3 pl-3 text-base whitespace-nowrap transition-colors outline-none select-none focus-visible:ring-3 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3 data-[size=default]:h-9 data-[size=sm]:h-8 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
33
|
+
className,
|
|
34
|
+
)}
|
|
35
|
+
{...props}
|
|
36
|
+
>
|
|
37
|
+
{children}
|
|
38
|
+
<SelectPrimitive.Icon render={<ChevronDownIcon className="text-muted-foreground pointer-events-none size-4" />} />
|
|
39
|
+
</SelectPrimitive.Trigger>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function SelectContent({
|
|
44
|
+
className,
|
|
45
|
+
children,
|
|
46
|
+
side = "bottom",
|
|
47
|
+
sideOffset = 4,
|
|
48
|
+
align = "center",
|
|
49
|
+
alignOffset = 0,
|
|
50
|
+
alignItemWithTrigger = true,
|
|
51
|
+
...props
|
|
52
|
+
}: SelectPrimitive.Popup.Props &
|
|
53
|
+
Pick<SelectPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset" | "alignItemWithTrigger">) {
|
|
54
|
+
return (
|
|
55
|
+
<SelectPrimitive.Portal>
|
|
56
|
+
<SelectPrimitive.Positioner
|
|
57
|
+
side={side}
|
|
58
|
+
sideOffset={sideOffset}
|
|
59
|
+
align={align}
|
|
60
|
+
alignOffset={alignOffset}
|
|
61
|
+
alignItemWithTrigger={alignItemWithTrigger}
|
|
62
|
+
className="isolate z-50"
|
|
63
|
+
>
|
|
64
|
+
<SelectPrimitive.Popup
|
|
65
|
+
data-slot="select-content"
|
|
66
|
+
data-align-trigger={alignItemWithTrigger}
|
|
67
|
+
className={cn(
|
|
68
|
+
"bg-popover text-popover-foreground ring-foreground/10 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg shadow-md ring-1 duration-100 data-[align-trigger=true]:animate-none",
|
|
69
|
+
className,
|
|
70
|
+
)}
|
|
71
|
+
{...props}
|
|
72
|
+
>
|
|
73
|
+
<SelectScrollUpButton />
|
|
74
|
+
<SelectPrimitive.List>{children}</SelectPrimitive.List>
|
|
75
|
+
<SelectScrollDownButton />
|
|
76
|
+
</SelectPrimitive.Popup>
|
|
77
|
+
</SelectPrimitive.Positioner>
|
|
78
|
+
</SelectPrimitive.Portal>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props) {
|
|
83
|
+
return (
|
|
84
|
+
<SelectPrimitive.GroupLabel
|
|
85
|
+
data-slot="select-label"
|
|
86
|
+
className={cn("text-muted-foreground px-1.5 py-1 text-xs", className)}
|
|
87
|
+
{...props}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Props) {
|
|
93
|
+
return (
|
|
94
|
+
<SelectPrimitive.Item
|
|
95
|
+
data-slot="select-item"
|
|
96
|
+
className={cn(
|
|
97
|
+
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground relative flex w-full 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 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
98
|
+
className,
|
|
99
|
+
)}
|
|
100
|
+
{...props}
|
|
101
|
+
>
|
|
102
|
+
<SelectPrimitive.ItemText className="flex flex-1 shrink-0 gap-2 whitespace-nowrap">
|
|
103
|
+
{children}
|
|
104
|
+
</SelectPrimitive.ItemText>
|
|
105
|
+
<SelectPrimitive.ItemIndicator
|
|
106
|
+
render={<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />}
|
|
107
|
+
>
|
|
108
|
+
<CheckIcon className="pointer-events-none" />
|
|
109
|
+
</SelectPrimitive.ItemIndicator>
|
|
110
|
+
</SelectPrimitive.Item>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function SelectSeparator({ className, ...props }: SelectPrimitive.Separator.Props) {
|
|
115
|
+
return (
|
|
116
|
+
<SelectPrimitive.Separator
|
|
117
|
+
data-slot="select-separator"
|
|
118
|
+
className={cn("bg-border pointer-events-none -mx-1 my-1 h-px", className)}
|
|
119
|
+
{...props}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {
|
|
125
|
+
return (
|
|
126
|
+
<SelectPrimitive.ScrollUpArrow
|
|
127
|
+
data-slot="select-scroll-up-button"
|
|
128
|
+
className={cn(
|
|
129
|
+
"bg-popover top-0 z-10 flex w-full cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
130
|
+
className,
|
|
131
|
+
)}
|
|
132
|
+
{...props}
|
|
133
|
+
>
|
|
134
|
+
<ChevronUpIcon />
|
|
135
|
+
</SelectPrimitive.ScrollUpArrow>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function SelectScrollDownButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {
|
|
140
|
+
return (
|
|
141
|
+
<SelectPrimitive.ScrollDownArrow
|
|
142
|
+
data-slot="select-scroll-down-button"
|
|
143
|
+
className={cn(
|
|
144
|
+
"bg-popover bottom-0 z-10 flex w-full cursor-default items-center justify-center py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
145
|
+
className,
|
|
146
|
+
)}
|
|
147
|
+
{...props}
|
|
148
|
+
>
|
|
149
|
+
<ChevronDownIcon />
|
|
150
|
+
</SelectPrimitive.ScrollDownArrow>
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export {
|
|
155
|
+
Select,
|
|
156
|
+
SelectContent,
|
|
157
|
+
SelectGroup,
|
|
158
|
+
SelectItem,
|
|
159
|
+
SelectLabel,
|
|
160
|
+
SelectScrollDownButton,
|
|
161
|
+
SelectScrollUpButton,
|
|
162
|
+
SelectSeparator,
|
|
163
|
+
SelectTrigger,
|
|
164
|
+
SelectValue,
|
|
165
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Separator as SeparatorPrimitive } from "@base-ui/react/separator";
|
|
4
|
+
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
|
|
7
|
+
function Separator({ className, orientation = "horizontal", ...props }: SeparatorPrimitive.Props) {
|
|
8
|
+
return (
|
|
9
|
+
<SeparatorPrimitive
|
|
10
|
+
data-slot="separator"
|
|
11
|
+
orientation={orientation}
|
|
12
|
+
className={cn(
|
|
13
|
+
"bg-border shrink-0 data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { Separator };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { Dialog as SheetPrimitive } from "@base-ui/react/dialog";
|
|
5
|
+
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
import { Button } from "./button";
|
|
8
|
+
import { XIcon } from "lucide-react";
|
|
9
|
+
|
|
10
|
+
function Sheet({ ...props }: SheetPrimitive.Root.Props) {
|
|
11
|
+
return <SheetPrimitive.Root data-slot="sheet" {...props} />;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {
|
|
15
|
+
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function SheetClose({ ...props }: SheetPrimitive.Close.Props) {
|
|
19
|
+
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {
|
|
23
|
+
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {
|
|
27
|
+
return (
|
|
28
|
+
<SheetPrimitive.Backdrop
|
|
29
|
+
data-slot="sheet-overlay"
|
|
30
|
+
className={cn(
|
|
31
|
+
"fixed inset-0 z-50 bg-black/10 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs",
|
|
32
|
+
className,
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function SheetContent({
|
|
40
|
+
className,
|
|
41
|
+
children,
|
|
42
|
+
side = "right",
|
|
43
|
+
showCloseButton = true,
|
|
44
|
+
...props
|
|
45
|
+
}: SheetPrimitive.Popup.Props & {
|
|
46
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
47
|
+
showCloseButton?: boolean;
|
|
48
|
+
}) {
|
|
49
|
+
return (
|
|
50
|
+
<SheetPortal>
|
|
51
|
+
<SheetOverlay />
|
|
52
|
+
<SheetPrimitive.Popup
|
|
53
|
+
data-slot="sheet-content"
|
|
54
|
+
data-side={side}
|
|
55
|
+
className={cn(
|
|
56
|
+
"bg-background fixed z-50 flex flex-col gap-4 bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-10 data-[side=bottom]:data-starting-style:translate-y-10 data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:-translate-x-10 data-[side=left]:data-starting-style:-translate-x-10 data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-10 data-[side=right]:data-starting-style:translate-x-10 data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:-translate-y-10 data-[side=top]:data-starting-style:-translate-y-10 data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm",
|
|
57
|
+
className,
|
|
58
|
+
)}
|
|
59
|
+
{...props}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
{showCloseButton && (
|
|
63
|
+
<SheetPrimitive.Close
|
|
64
|
+
data-slot="sheet-close"
|
|
65
|
+
render={<Button variant="ghost" className="absolute top-3 right-3" size="icon-sm" />}
|
|
66
|
+
>
|
|
67
|
+
<XIcon />
|
|
68
|
+
<span className="sr-only">Close</span>
|
|
69
|
+
</SheetPrimitive.Close>
|
|
70
|
+
)}
|
|
71
|
+
</SheetPrimitive.Popup>
|
|
72
|
+
</SheetPortal>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
|
|
77
|
+
return <div data-slot="sheet-header" className={cn("flex flex-col gap-0.5 p-4", className)} {...props} />;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
|
|
81
|
+
return <div data-slot="sheet-footer" className={cn("mt-auto flex flex-col gap-2 p-4", className)} {...props} />;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {
|
|
85
|
+
return (
|
|
86
|
+
<SheetPrimitive.Title
|
|
87
|
+
data-slot="sheet-title"
|
|
88
|
+
className={cn("text-foreground text-base font-medium", className)}
|
|
89
|
+
{...props}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function SheetDescription({ className, ...props }: SheetPrimitive.Description.Props) {
|
|
95
|
+
return (
|
|
96
|
+
<SheetPrimitive.Description
|
|
97
|
+
data-slot="sheet-description"
|
|
98
|
+
className={cn("text-muted-foreground text-sm", className)}
|
|
99
|
+
{...props}
|
|
100
|
+
/>
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export { Sheet, SheetTrigger, SheetClose, SheetContent, SheetHeader, SheetFooter, SheetTitle, SheetDescription };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
function Table({ className, ...props }: React.ComponentProps<"table">) {
|
|
6
|
+
return (
|
|
7
|
+
<div data-slot="table-container" className="relative w-full overflow-x-auto">
|
|
8
|
+
<table
|
|
9
|
+
data-slot="table"
|
|
10
|
+
className={cn("bg-muted/30 w-full caption-bottom rounded-lg text-sm", className)}
|
|
11
|
+
{...props}
|
|
12
|
+
/>
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function TableHeader({ className, ...props }: React.ComponentProps<"thead">) {
|
|
18
|
+
return <thead data-slot="table-header" className={cn("bg-muted/50 [&_tr]:border-b", className)} {...props} />;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function TableBody({ className, ...props }: React.ComponentProps<"tbody">) {
|
|
22
|
+
return <tbody data-slot="table-body" className={cn("[&_tr:last-child]:border-0", className)} {...props} />;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function TableFooter({ className, ...props }: React.ComponentProps<"tfoot">) {
|
|
26
|
+
return (
|
|
27
|
+
<tfoot
|
|
28
|
+
data-slot="table-footer"
|
|
29
|
+
className={cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className)}
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
|
|
36
|
+
return (
|
|
37
|
+
<tr
|
|
38
|
+
data-slot="table-row"
|
|
39
|
+
className={cn("hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors", className)}
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function TableHead({ className, ...props }: React.ComponentProps<"th">) {
|
|
46
|
+
return (
|
|
47
|
+
<th
|
|
48
|
+
data-slot="table-head"
|
|
49
|
+
className={cn(
|
|
50
|
+
"text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0",
|
|
51
|
+
className,
|
|
52
|
+
)}
|
|
53
|
+
{...props}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function TableCell({ className, ...props }: React.ComponentProps<"td">) {
|
|
59
|
+
return (
|
|
60
|
+
<td
|
|
61
|
+
data-slot="table-cell"
|
|
62
|
+
className={cn("p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0", className)}
|
|
63
|
+
{...props}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function TableCaption({ className, ...props }: React.ComponentProps<"caption">) {
|
|
69
|
+
return (
|
|
70
|
+
<caption data-slot="table-caption" className={cn("text-muted-foreground mt-4 text-sm", className)} {...props} />
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
function Textarea({ className, ...props }: React.ComponentProps<"textarea">) {
|
|
6
|
+
return (
|
|
7
|
+
<textarea
|
|
8
|
+
data-slot="textarea"
|
|
9
|
+
className={cn(
|
|
10
|
+
"border-input hover:border-foreground/20 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 flex field-sizing-content min-h-16 w-full rounded-lg border px-3 py-2.5 text-base transition-colors outline-none read-only:cursor-not-allowed focus-visible:ring-3 read-only:focus-visible:ring-0 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:ring-3",
|
|
11
|
+
className,
|
|
12
|
+
)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { Textarea };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Tooltip as TooltipPrimitive } from "@base-ui/react/tooltip";
|
|
2
|
+
|
|
3
|
+
import { cn } from "../../lib/utils";
|
|
4
|
+
|
|
5
|
+
function TooltipProvider({ delay = 0, ...props }: TooltipPrimitive.Provider.Props) {
|
|
6
|
+
return <TooltipPrimitive.Provider data-slot="tooltip-provider" delay={delay} {...props} />;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function Tooltip({ ...props }: TooltipPrimitive.Root.Props) {
|
|
10
|
+
return <TooltipPrimitive.Root data-slot="tooltip" {...props} />;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {
|
|
14
|
+
return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function TooltipContent({
|
|
18
|
+
className,
|
|
19
|
+
side = "top",
|
|
20
|
+
sideOffset = 4,
|
|
21
|
+
align = "center",
|
|
22
|
+
alignOffset = 0,
|
|
23
|
+
children,
|
|
24
|
+
...props
|
|
25
|
+
}: TooltipPrimitive.Popup.Props &
|
|
26
|
+
Pick<TooltipPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">) {
|
|
27
|
+
return (
|
|
28
|
+
<TooltipPrimitive.Portal>
|
|
29
|
+
<TooltipPrimitive.Positioner
|
|
30
|
+
align={align}
|
|
31
|
+
alignOffset={alignOffset}
|
|
32
|
+
side={side}
|
|
33
|
+
sideOffset={sideOffset}
|
|
34
|
+
className="isolate z-50"
|
|
35
|
+
>
|
|
36
|
+
<TooltipPrimitive.Popup
|
|
37
|
+
data-slot="tooltip-content"
|
|
38
|
+
className={cn(
|
|
39
|
+
"bg-foreground text-background data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md px-3 py-1.5 text-xs has-data-[slot=kbd]:pr-1.5 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm",
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
>
|
|
44
|
+
{children}
|
|
45
|
+
<TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5" />
|
|
46
|
+
</TooltipPrimitive.Popup>
|
|
47
|
+
</TooltipPrimitive.Positioner>
|
|
48
|
+
</TooltipPrimitive.Portal>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
|