ucode-agent 1.3.0 → 1.5.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 (56) hide show
  1. package/README.md +42 -12
  2. package/package.json +5 -3
  3. package/skills/build-app/SKILL.md +23 -3
  4. package/skills/ui-ux/SKILL.md +5 -1
  5. package/src/core/loop.js +181 -20
  6. package/src/core/provider.js +40 -12
  7. package/src/core/updater.js +95 -0
  8. package/src/tools/browser.js +258 -0
  9. package/src/tools/index.js +51 -1
  10. package/src/tools/scaffold.js +130 -0
  11. package/src/tools/shell.js +8 -1
  12. package/src/ui/screen.js +20 -6
  13. package/templates/next-shadcn/AGENTS.md +9 -0
  14. package/templates/next-shadcn/README.md +9 -0
  15. package/templates/next-shadcn/TEMPLATE.md +39 -0
  16. package/templates/next-shadcn/_gitignore +41 -0
  17. package/templates/next-shadcn/_package-lock.json +10278 -0
  18. package/templates/next-shadcn/components.json +25 -0
  19. package/templates/next-shadcn/eslint.config.mjs +18 -0
  20. package/templates/next-shadcn/next-env.d.ts +5 -0
  21. package/templates/next-shadcn/next.config.ts +7 -0
  22. package/templates/next-shadcn/package.json +37 -0
  23. package/templates/next-shadcn/postcss.config.mjs +7 -0
  24. package/templates/next-shadcn/src/app/favicon.ico +0 -0
  25. package/templates/next-shadcn/src/app/globals.css +155 -0
  26. package/templates/next-shadcn/src/app/layout.tsx +42 -0
  27. package/templates/next-shadcn/src/app/page.tsx +14 -0
  28. package/templates/next-shadcn/src/components/theme-provider.tsx +7 -0
  29. package/templates/next-shadcn/src/components/theme-toggle.tsx +27 -0
  30. package/templates/next-shadcn/src/components/ui/alert-dialog.tsx +187 -0
  31. package/templates/next-shadcn/src/components/ui/avatar.tsx +108 -0
  32. package/templates/next-shadcn/src/components/ui/badge.tsx +51 -0
  33. package/templates/next-shadcn/src/components/ui/button.tsx +57 -0
  34. package/templates/next-shadcn/src/components/ui/calendar.tsx +221 -0
  35. package/templates/next-shadcn/src/components/ui/card.tsx +102 -0
  36. package/templates/next-shadcn/src/components/ui/checkbox.tsx +28 -0
  37. package/templates/next-shadcn/src/components/ui/command.tsx +196 -0
  38. package/templates/next-shadcn/src/components/ui/dialog.tsx +160 -0
  39. package/templates/next-shadcn/src/components/ui/dropdown-menu.tsx +267 -0
  40. package/templates/next-shadcn/src/components/ui/input-group.tsx +158 -0
  41. package/templates/next-shadcn/src/components/ui/input.tsx +19 -0
  42. package/templates/next-shadcn/src/components/ui/label.tsx +19 -0
  43. package/templates/next-shadcn/src/components/ui/popover.tsx +89 -0
  44. package/templates/next-shadcn/src/components/ui/progress.tsx +82 -0
  45. package/templates/next-shadcn/src/components/ui/scroll-area.tsx +54 -0
  46. package/templates/next-shadcn/src/components/ui/select.tsx +200 -0
  47. package/templates/next-shadcn/src/components/ui/separator.tsx +24 -0
  48. package/templates/next-shadcn/src/components/ui/sheet.tsx +138 -0
  49. package/templates/next-shadcn/src/components/ui/skeleton.tsx +13 -0
  50. package/templates/next-shadcn/src/components/ui/sonner.tsx +49 -0
  51. package/templates/next-shadcn/src/components/ui/switch.tsx +31 -0
  52. package/templates/next-shadcn/src/components/ui/tabs.tsx +81 -0
  53. package/templates/next-shadcn/src/components/ui/textarea.tsx +17 -0
  54. package/templates/next-shadcn/src/components/ui/tooltip.tsx +65 -0
  55. package/templates/next-shadcn/src/lib/utils.ts +1 -0
  56. package/templates/next-shadcn/tsconfig.json +34 -0
@@ -0,0 +1,89 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Popover as PopoverPrimitive } from "@base-ui/react/popover"
5
+ import { cn } from "cn"
6
+
7
+ function Popover({ ...props }: PopoverPrimitive.Root.Props) {
8
+ return <PopoverPrimitive.Root data-slot="popover" {...props} />
9
+ }
10
+
11
+ function PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {
12
+ return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
13
+ }
14
+
15
+ function PopoverContent({
16
+ className,
17
+ align = "center",
18
+ alignOffset = 0,
19
+ side = "bottom",
20
+ sideOffset = 4,
21
+ ...props
22
+ }: PopoverPrimitive.Popup.Props &
23
+ Pick<
24
+ PopoverPrimitive.Positioner.Props,
25
+ "align" | "alignOffset" | "side" | "sideOffset"
26
+ >) {
27
+ return (
28
+ <PopoverPrimitive.Portal>
29
+ <PopoverPrimitive.Positioner
30
+ align={align}
31
+ alignOffset={alignOffset}
32
+ side={side}
33
+ sideOffset={sideOffset}
34
+ className="isolate z-50"
35
+ >
36
+ <PopoverPrimitive.Popup
37
+ data-slot="popover-content"
38
+ className={cn(
39
+ "z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 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",
40
+ className
41
+ )}
42
+ {...props}
43
+ />
44
+ </PopoverPrimitive.Positioner>
45
+ </PopoverPrimitive.Portal>
46
+ )
47
+ }
48
+
49
+ function PopoverHeader({ className, ...props }: React.ComponentProps<"div">) {
50
+ return (
51
+ <div
52
+ data-slot="popover-header"
53
+ className={cn("flex flex-col gap-0.5 text-sm", className)}
54
+ {...props}
55
+ />
56
+ )
57
+ }
58
+
59
+ function PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {
60
+ return (
61
+ <PopoverPrimitive.Title
62
+ data-slot="popover-title"
63
+ className={cn("font-medium", className)}
64
+ {...props}
65
+ />
66
+ )
67
+ }
68
+
69
+ function PopoverDescription({
70
+ className,
71
+ ...props
72
+ }: PopoverPrimitive.Description.Props) {
73
+ return (
74
+ <PopoverPrimitive.Description
75
+ data-slot="popover-description"
76
+ className={cn("text-muted-foreground", className)}
77
+ {...props}
78
+ />
79
+ )
80
+ }
81
+
82
+ export {
83
+ Popover,
84
+ PopoverContent,
85
+ PopoverDescription,
86
+ PopoverHeader,
87
+ PopoverTitle,
88
+ PopoverTrigger,
89
+ }
@@ -0,0 +1,82 @@
1
+ "use client"
2
+
3
+ import { Progress as ProgressPrimitive } from "@base-ui/react/progress"
4
+ import { cn } from "cn"
5
+
6
+ function Progress({
7
+ className,
8
+ children,
9
+ value,
10
+ ...props
11
+ }: ProgressPrimitive.Root.Props) {
12
+ return (
13
+ <ProgressPrimitive.Root
14
+ value={value}
15
+ data-slot="progress"
16
+ className={cn("flex flex-wrap gap-3", className)}
17
+ {...props}
18
+ >
19
+ {children}
20
+ <ProgressTrack>
21
+ <ProgressIndicator />
22
+ </ProgressTrack>
23
+ </ProgressPrimitive.Root>
24
+ )
25
+ }
26
+
27
+ function ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {
28
+ return (
29
+ <ProgressPrimitive.Track
30
+ className={cn(
31
+ "relative flex h-1 w-full items-center overflow-x-hidden rounded-full bg-muted",
32
+ className
33
+ )}
34
+ data-slot="progress-track"
35
+ {...props}
36
+ />
37
+ )
38
+ }
39
+
40
+ function ProgressIndicator({
41
+ className,
42
+ ...props
43
+ }: ProgressPrimitive.Indicator.Props) {
44
+ return (
45
+ <ProgressPrimitive.Indicator
46
+ data-slot="progress-indicator"
47
+ className={cn("h-full bg-primary transition-all", className)}
48
+ {...props}
49
+ />
50
+ )
51
+ }
52
+
53
+ function ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {
54
+ return (
55
+ <ProgressPrimitive.Label
56
+ className={cn("text-sm font-medium", className)}
57
+ data-slot="progress-label"
58
+ {...props}
59
+ />
60
+ )
61
+ }
62
+
63
+ function ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {
64
+ return (
65
+ <ProgressPrimitive.Value
66
+ className={cn(
67
+ "ml-auto text-sm text-muted-foreground tabular-nums",
68
+ className
69
+ )}
70
+ data-slot="progress-value"
71
+ {...props}
72
+ />
73
+ )
74
+ }
75
+
76
+ export {
77
+ Progress,
78
+ ProgressTrack,
79
+ ProgressIndicator,
80
+ ProgressLabel,
81
+ ProgressValue,
82
+ }
@@ -0,0 +1,54 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { ScrollArea as ScrollAreaPrimitive } from "@base-ui/react/scroll-area"
5
+ import { cn } from "cn"
6
+
7
+ function ScrollArea({
8
+ className,
9
+ children,
10
+ ...props
11
+ }: ScrollAreaPrimitive.Root.Props) {
12
+ return (
13
+ <ScrollAreaPrimitive.Root
14
+ data-slot="scroll-area"
15
+ className={cn("relative", className)}
16
+ {...props}
17
+ >
18
+ <ScrollAreaPrimitive.Viewport
19
+ data-slot="scroll-area-viewport"
20
+ className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
21
+ >
22
+ {children}
23
+ </ScrollAreaPrimitive.Viewport>
24
+ <ScrollBar />
25
+ <ScrollAreaPrimitive.Corner />
26
+ </ScrollAreaPrimitive.Root>
27
+ )
28
+ }
29
+
30
+ function ScrollBar({
31
+ className,
32
+ orientation = "vertical",
33
+ ...props
34
+ }: ScrollAreaPrimitive.Scrollbar.Props) {
35
+ return (
36
+ <ScrollAreaPrimitive.Scrollbar
37
+ data-slot="scroll-area-scrollbar"
38
+ data-orientation={orientation}
39
+ orientation={orientation}
40
+ className={cn(
41
+ "flex touch-none p-px transition-colors select-none data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent",
42
+ className
43
+ )}
44
+ {...props}
45
+ >
46
+ <ScrollAreaPrimitive.Thumb
47
+ data-slot="scroll-area-thumb"
48
+ className="relative flex-1 rounded-full bg-border"
49
+ />
50
+ </ScrollAreaPrimitive.Scrollbar>
51
+ )
52
+ }
53
+
54
+ export { ScrollArea, ScrollBar }
@@ -0,0 +1,200 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Select as SelectPrimitive } from "@base-ui/react/select"
5
+ import { cn } from "cn"
6
+ import { ChevronDownIcon, CheckIcon, ChevronUpIcon } from "lucide-react"
7
+
8
+ const Select = SelectPrimitive.Root
9
+
10
+ function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
11
+ return (
12
+ <SelectPrimitive.Group
13
+ data-slot="select-group"
14
+ className={cn("scroll-my-1 p-1", className)}
15
+ {...props}
16
+ />
17
+ )
18
+ }
19
+
20
+ function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
21
+ return (
22
+ <SelectPrimitive.Value
23
+ data-slot="select-value"
24
+ className={cn("flex flex-1 text-left", className)}
25
+ {...props}
26
+ />
27
+ )
28
+ }
29
+
30
+ function SelectTrigger({
31
+ className,
32
+ size = "default",
33
+ children,
34
+ ...props
35
+ }: SelectPrimitive.Trigger.Props & {
36
+ size?: "sm" | "default"
37
+ }) {
38
+ return (
39
+ <SelectPrimitive.Trigger
40
+ data-slot="select-trigger"
41
+ data-size={size}
42
+ className={cn(
43
+ "flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 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 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
44
+ className
45
+ )}
46
+ {...props}
47
+ >
48
+ {children}
49
+ <SelectPrimitive.Icon
50
+ render={
51
+ <ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />
52
+ }
53
+ />
54
+ </SelectPrimitive.Trigger>
55
+ )
56
+ }
57
+
58
+ function SelectContent({
59
+ className,
60
+ children,
61
+ side = "bottom",
62
+ sideOffset = 4,
63
+ align = "center",
64
+ alignOffset = 0,
65
+ alignItemWithTrigger = true,
66
+ ...props
67
+ }: SelectPrimitive.Popup.Props &
68
+ Pick<
69
+ SelectPrimitive.Positioner.Props,
70
+ "align" | "alignOffset" | "side" | "sideOffset" | "alignItemWithTrigger"
71
+ >) {
72
+ return (
73
+ <SelectPrimitive.Portal>
74
+ <SelectPrimitive.Positioner
75
+ side={side}
76
+ sideOffset={sideOffset}
77
+ align={align}
78
+ alignOffset={alignOffset}
79
+ alignItemWithTrigger={alignItemWithTrigger}
80
+ className="isolate z-50"
81
+ >
82
+ <SelectPrimitive.Popup
83
+ data-slot="select-content"
84
+ data-align-trigger={alignItemWithTrigger}
85
+ className={cn("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 bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none 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", className )}
86
+ {...props}
87
+ >
88
+ <SelectScrollUpButton />
89
+ <SelectPrimitive.List>{children}</SelectPrimitive.List>
90
+ <SelectScrollDownButton />
91
+ </SelectPrimitive.Popup>
92
+ </SelectPrimitive.Positioner>
93
+ </SelectPrimitive.Portal>
94
+ )
95
+ }
96
+
97
+ function SelectLabel({
98
+ className,
99
+ ...props
100
+ }: SelectPrimitive.GroupLabel.Props) {
101
+ return (
102
+ <SelectPrimitive.GroupLabel
103
+ data-slot="select-label"
104
+ className={cn("px-1.5 py-1 text-xs text-muted-foreground", className)}
105
+ {...props}
106
+ />
107
+ )
108
+ }
109
+
110
+ function SelectItem({
111
+ className,
112
+ children,
113
+ ...props
114
+ }: SelectPrimitive.Item.Props) {
115
+ return (
116
+ <SelectPrimitive.Item
117
+ data-slot="select-item"
118
+ className={cn(
119
+ "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 focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground 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",
120
+ className
121
+ )}
122
+ {...props}
123
+ >
124
+ <SelectPrimitive.ItemText className="flex flex-1 shrink-0 gap-2 whitespace-nowrap">
125
+ {children}
126
+ </SelectPrimitive.ItemText>
127
+ <SelectPrimitive.ItemIndicator
128
+ render={
129
+ <span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />
130
+ }
131
+ >
132
+ <CheckIcon className="pointer-events-none" />
133
+ </SelectPrimitive.ItemIndicator>
134
+ </SelectPrimitive.Item>
135
+ )
136
+ }
137
+
138
+ function SelectSeparator({
139
+ className,
140
+ ...props
141
+ }: SelectPrimitive.Separator.Props) {
142
+ return (
143
+ <SelectPrimitive.Separator
144
+ data-slot="select-separator"
145
+ className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
146
+ {...props}
147
+ />
148
+ )
149
+ }
150
+
151
+ function SelectScrollUpButton({
152
+ className,
153
+ ...props
154
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {
155
+ return (
156
+ <SelectPrimitive.ScrollUpArrow
157
+ data-slot="select-scroll-up-button"
158
+ className={cn(
159
+ "top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
160
+ className
161
+ )}
162
+ {...props}
163
+ >
164
+ <ChevronUpIcon
165
+ />
166
+ </SelectPrimitive.ScrollUpArrow>
167
+ )
168
+ }
169
+
170
+ function SelectScrollDownButton({
171
+ className,
172
+ ...props
173
+ }: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {
174
+ return (
175
+ <SelectPrimitive.ScrollDownArrow
176
+ data-slot="select-scroll-down-button"
177
+ className={cn(
178
+ "bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
179
+ className
180
+ )}
181
+ {...props}
182
+ >
183
+ <ChevronDownIcon
184
+ />
185
+ </SelectPrimitive.ScrollDownArrow>
186
+ )
187
+ }
188
+
189
+ export {
190
+ Select,
191
+ SelectContent,
192
+ SelectGroup,
193
+ SelectItem,
194
+ SelectLabel,
195
+ SelectScrollDownButton,
196
+ SelectScrollUpButton,
197
+ SelectSeparator,
198
+ SelectTrigger,
199
+ SelectValue,
200
+ }
@@ -0,0 +1,24 @@
1
+ "use client"
2
+
3
+ import { Separator as SeparatorPrimitive } from "@base-ui/react/separator"
4
+ import { cn } from "cn"
5
+
6
+ function Separator({
7
+ className,
8
+ orientation = "horizontal",
9
+ ...props
10
+ }: SeparatorPrimitive.Props) {
11
+ return (
12
+ <SeparatorPrimitive
13
+ data-slot="separator"
14
+ orientation={orientation}
15
+ className={cn(
16
+ "shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch",
17
+ className
18
+ )}
19
+ {...props}
20
+ />
21
+ )
22
+ }
23
+
24
+ export { Separator }
@@ -0,0 +1,138 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Dialog as SheetPrimitive } from "@base-ui/react/dialog"
5
+ import { cn } from "cn"
6
+
7
+ import { Button } from "@/components/ui/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
+ "fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground 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-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] 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-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] 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-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] 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-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] 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={
66
+ <Button
67
+ variant="ghost"
68
+ className="absolute top-3 right-3"
69
+ size="icon-sm"
70
+ />
71
+ }
72
+ >
73
+ <XIcon
74
+ />
75
+ <span className="sr-only">Close</span>
76
+ </SheetPrimitive.Close>
77
+ )}
78
+ </SheetPrimitive.Popup>
79
+ </SheetPortal>
80
+ )
81
+ }
82
+
83
+ function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
84
+ return (
85
+ <div
86
+ data-slot="sheet-header"
87
+ className={cn("flex flex-col gap-0.5 p-4", className)}
88
+ {...props}
89
+ />
90
+ )
91
+ }
92
+
93
+ function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
94
+ return (
95
+ <div
96
+ data-slot="sheet-footer"
97
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
98
+ {...props}
99
+ />
100
+ )
101
+ }
102
+
103
+ function SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {
104
+ return (
105
+ <SheetPrimitive.Title
106
+ data-slot="sheet-title"
107
+ className={cn(
108
+ "font-heading text-base font-medium text-foreground",
109
+ className
110
+ )}
111
+ {...props}
112
+ />
113
+ )
114
+ }
115
+
116
+ function SheetDescription({
117
+ className,
118
+ ...props
119
+ }: SheetPrimitive.Description.Props) {
120
+ return (
121
+ <SheetPrimitive.Description
122
+ data-slot="sheet-description"
123
+ className={cn("text-sm text-muted-foreground", className)}
124
+ {...props}
125
+ />
126
+ )
127
+ }
128
+
129
+ export {
130
+ Sheet,
131
+ SheetTrigger,
132
+ SheetClose,
133
+ SheetContent,
134
+ SheetHeader,
135
+ SheetFooter,
136
+ SheetTitle,
137
+ SheetDescription,
138
+ }
@@ -0,0 +1,13 @@
1
+ import { cn } from "cn"
2
+
3
+ function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
4
+ return (
5
+ <div
6
+ data-slot="skeleton"
7
+ className={cn("animate-pulse rounded-md bg-muted", className)}
8
+ {...props}
9
+ />
10
+ )
11
+ }
12
+
13
+ export { Skeleton }
@@ -0,0 +1,49 @@
1
+ "use client"
2
+
3
+ import { useTheme } from "next-themes"
4
+ import { Toaster as Sonner, type ToasterProps } from "sonner"
5
+ import { CircleCheckIcon, InfoIcon, TriangleAlertIcon, OctagonXIcon, Loader2Icon } from "lucide-react"
6
+
7
+ const Toaster = ({ ...props }: ToasterProps) => {
8
+ const { theme = "system" } = useTheme()
9
+
10
+ return (
11
+ <Sonner
12
+ theme={theme as ToasterProps["theme"]}
13
+ className="toaster group"
14
+ icons={{
15
+ success: (
16
+ <CircleCheckIcon className="size-4" />
17
+ ),
18
+ info: (
19
+ <InfoIcon className="size-4" />
20
+ ),
21
+ warning: (
22
+ <TriangleAlertIcon className="size-4" />
23
+ ),
24
+ error: (
25
+ <OctagonXIcon className="size-4" />
26
+ ),
27
+ loading: (
28
+ <Loader2Icon className="size-4 animate-spin" />
29
+ ),
30
+ }}
31
+ style={
32
+ {
33
+ "--normal-bg": "var(--popover)",
34
+ "--normal-text": "var(--popover-foreground)",
35
+ "--normal-border": "var(--border)",
36
+ "--border-radius": "var(--radius)",
37
+ } as React.CSSProperties
38
+ }
39
+ toastOptions={{
40
+ classNames: {
41
+ toast: "cn-toast",
42
+ },
43
+ }}
44
+ {...props}
45
+ />
46
+ )
47
+ }
48
+
49
+ export { Toaster }
@@ -0,0 +1,31 @@
1
+ "use client"
2
+
3
+ import { Switch as SwitchPrimitive } from "@base-ui/react/switch"
4
+ import { cn } from "cn"
5
+
6
+ function Switch({
7
+ className,
8
+ size = "default",
9
+ ...props
10
+ }: SwitchPrimitive.Root.Props & {
11
+ size?: "sm" | "default"
12
+ }) {
13
+ return (
14
+ <SwitchPrimitive.Root
15
+ data-slot="switch"
16
+ data-size={size}
17
+ className={cn(
18
+ "peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50",
19
+ className
20
+ )}
21
+ {...props}
22
+ >
23
+ <SwitchPrimitive.Thumb
24
+ data-slot="switch-thumb"
25
+ className="pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground"
26
+ />
27
+ </SwitchPrimitive.Root>
28
+ )
29
+ }
30
+
31
+ export { Switch }