@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.
Files changed (93) hide show
  1. package/README.md +28 -0
  2. package/admin/components/AdminCard.astro +25 -0
  3. package/admin/components/AiGenerateButton.tsx +102 -0
  4. package/admin/components/AssetsGrid.tsx +711 -0
  5. package/admin/components/BlockEditor.tsx +996 -0
  6. package/admin/components/CheckboxField.tsx +31 -0
  7. package/admin/components/DocumentActions.tsx +317 -0
  8. package/admin/components/DocumentLock.tsx +54 -0
  9. package/admin/components/DocumentsDataTable.tsx +804 -0
  10. package/admin/components/FieldControl.astro +397 -0
  11. package/admin/components/FocalPointSelector.tsx +100 -0
  12. package/admin/components/ImageBrowseDialog.tsx +176 -0
  13. package/admin/components/ImagePicker.tsx +149 -0
  14. package/admin/components/InternalLinkPicker.tsx +80 -0
  15. package/admin/components/LiveHeading.tsx +17 -0
  16. package/admin/components/MobileSidebar.tsx +29 -0
  17. package/admin/components/RelationField.tsx +204 -0
  18. package/admin/components/RichTextEditor.tsx +685 -0
  19. package/admin/components/SelectField.tsx +65 -0
  20. package/admin/components/SidebarUserMenu.tsx +99 -0
  21. package/admin/components/SlugField.tsx +77 -0
  22. package/admin/components/TaxonomySelect.tsx +52 -0
  23. package/admin/components/Toast.astro +40 -0
  24. package/admin/components/TreeItemsEditor.tsx +790 -0
  25. package/admin/components/TreeSelect.tsx +166 -0
  26. package/admin/components/UnsavedGuard.tsx +181 -0
  27. package/admin/components/tree-utils.ts +86 -0
  28. package/admin/components/ui/alert-dialog.tsx +92 -0
  29. package/admin/components/ui/badge.tsx +83 -0
  30. package/admin/components/ui/button.tsx +53 -0
  31. package/admin/components/ui/card.tsx +70 -0
  32. package/admin/components/ui/checkbox.tsx +28 -0
  33. package/admin/components/ui/collapsible.tsx +26 -0
  34. package/admin/components/ui/command.tsx +88 -0
  35. package/admin/components/ui/dialog.tsx +92 -0
  36. package/admin/components/ui/dropdown-menu.tsx +259 -0
  37. package/admin/components/ui/input.tsx +20 -0
  38. package/admin/components/ui/label.tsx +20 -0
  39. package/admin/components/ui/popover.tsx +42 -0
  40. package/admin/components/ui/select.tsx +165 -0
  41. package/admin/components/ui/separator.tsx +21 -0
  42. package/admin/components/ui/sheet.tsx +104 -0
  43. package/admin/components/ui/skeleton.tsx +7 -0
  44. package/admin/components/ui/table.tsx +74 -0
  45. package/admin/components/ui/textarea.tsx +18 -0
  46. package/admin/components/ui/tooltip.tsx +52 -0
  47. package/admin/layouts/AdminLayout.astro +340 -0
  48. package/admin/lib/utils.ts +19 -0
  49. package/dist/admin.js +92 -0
  50. package/dist/ai.js +67 -0
  51. package/dist/api.js +827 -0
  52. package/dist/assets.js +163 -0
  53. package/dist/auth.js +132 -0
  54. package/dist/blocks.js +110 -0
  55. package/dist/content.js +29 -0
  56. package/dist/create-admin.js +23 -0
  57. package/dist/define.js +36 -0
  58. package/dist/generator.js +370 -0
  59. package/dist/image.js +69 -0
  60. package/dist/index.js +16 -0
  61. package/dist/integration.js +256 -0
  62. package/dist/locks.js +37 -0
  63. package/dist/richtext.js +1 -0
  64. package/dist/runtime.js +26 -0
  65. package/dist/schema.js +13 -0
  66. package/dist/seed.js +84 -0
  67. package/dist/values.js +102 -0
  68. package/middleware/auth.ts +100 -0
  69. package/package.json +102 -0
  70. package/routes/api/cms/[collection]/[...path].ts +366 -0
  71. package/routes/api/cms/ai/alt-text.ts +25 -0
  72. package/routes/api/cms/ai/seo.ts +25 -0
  73. package/routes/api/cms/ai/translate.ts +31 -0
  74. package/routes/api/cms/assets/[id].ts +82 -0
  75. package/routes/api/cms/assets/folders.ts +81 -0
  76. package/routes/api/cms/assets/index.ts +23 -0
  77. package/routes/api/cms/assets/upload.ts +112 -0
  78. package/routes/api/cms/auth/invite.ts +166 -0
  79. package/routes/api/cms/auth/login.ts +124 -0
  80. package/routes/api/cms/auth/logout.ts +33 -0
  81. package/routes/api/cms/auth/setup.ts +77 -0
  82. package/routes/api/cms/cron/publish.ts +33 -0
  83. package/routes/api/cms/img/[...path].ts +24 -0
  84. package/routes/api/cms/locks/[...path].ts +37 -0
  85. package/routes/api/cms/preview/render.ts +36 -0
  86. package/routes/api/cms/references/[collection]/[id].ts +60 -0
  87. package/routes/pages/admin/[...path].astro +1104 -0
  88. package/routes/pages/admin/assets/[id].astro +183 -0
  89. package/routes/pages/admin/assets/index.astro +58 -0
  90. package/routes/pages/admin/invite.astro +116 -0
  91. package/routes/pages/admin/login.astro +57 -0
  92. package/routes/pages/admin/setup.astro +91 -0
  93. 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,7 @@
1
+ import { cn } from "../../lib/utils";
2
+
3
+ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
+ return <div data-slot="skeleton" className={cn("bg-muted animate-pulse rounded-md", className)} {...props} />;
5
+ }
6
+
7
+ export { Skeleton };
@@ -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 };