create-deesse-app 0.2.3 → 0.4.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 (103) hide show
  1. package/dist/src/copy.d.ts +1 -1
  2. package/dist/src/copy.d.ts.map +1 -1
  3. package/dist/src/copy.js +50 -71
  4. package/dist/src/copy.js.map +1 -1
  5. package/dist/src/index.js +3 -2
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/tsconfig.tsbuildinfo +1 -1
  8. package/package.json +4 -5
  9. package/templates/default/.agents/skills/shadcn/SKILL.md +242 -0
  10. package/templates/default/.agents/skills/shadcn/agents/openai.yml +5 -0
  11. package/templates/default/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
  12. package/templates/default/.agents/skills/shadcn/assets/shadcn.png +0 -0
  13. package/templates/default/.agents/skills/shadcn/cli.md +257 -0
  14. package/templates/default/.agents/skills/shadcn/customization.md +202 -0
  15. package/templates/default/.agents/skills/shadcn/evals/evals.json +47 -0
  16. package/templates/default/.agents/skills/shadcn/mcp.md +94 -0
  17. package/templates/default/.agents/skills/shadcn/rules/base-vs-radix.md +306 -0
  18. package/templates/default/.agents/skills/shadcn/rules/composition.md +195 -0
  19. package/templates/default/.agents/skills/shadcn/rules/forms.md +192 -0
  20. package/templates/default/.agents/skills/shadcn/rules/icons.md +101 -0
  21. package/templates/default/.agents/skills/shadcn/rules/styling.md +162 -0
  22. package/templates/default/AGENTS.md +5 -0
  23. package/templates/default/CLAUDE.md +1 -0
  24. package/templates/default/README.md +28 -0
  25. package/templates/default/components.json +25 -0
  26. package/templates/default/eslint.config.mjs +18 -0
  27. package/templates/default/next.config.ts +7 -0
  28. package/templates/default/package.json +50 -0
  29. package/templates/default/postcss.config.mjs +7 -0
  30. package/templates/default/public/file.svg +1 -0
  31. package/templates/default/public/globe.svg +1 -0
  32. package/templates/default/public/nesalia.svg +50 -0
  33. package/templates/default/public/window.svg +1 -0
  34. package/templates/default/skills-lock.json +10 -0
  35. package/templates/default/src/app/(deesse)/admin/[[...slug]]/page.tsx +20 -0
  36. package/templates/default/src/app/(deesse)/admin/layout.tsx +7 -0
  37. package/templates/default/src/app/(frontend)/page.tsx +50 -0
  38. package/templates/default/src/app/globals.css +130 -0
  39. package/templates/default/src/app/icon.svg +109 -0
  40. package/templates/default/src/app/layout.tsx +33 -0
  41. package/templates/default/src/app/page.tsx +50 -0
  42. package/templates/default/src/components/providers/index.tsx +9 -0
  43. package/templates/default/src/components/providers/theme-provider.tsx +11 -0
  44. package/templates/default/src/components/ui/accordion.tsx +81 -0
  45. package/templates/default/src/components/ui/alert-dialog.tsx +199 -0
  46. package/templates/default/src/components/ui/alert.tsx +76 -0
  47. package/templates/default/src/components/ui/aspect-ratio.tsx +11 -0
  48. package/templates/default/src/components/ui/avatar.tsx +112 -0
  49. package/templates/default/src/components/ui/badge.tsx +49 -0
  50. package/templates/default/src/components/ui/breadcrumb.tsx +122 -0
  51. package/templates/default/src/components/ui/button-group.tsx +83 -0
  52. package/templates/default/src/components/ui/button.tsx +67 -0
  53. package/templates/default/src/components/ui/calendar.tsx +222 -0
  54. package/templates/default/src/components/ui/card.tsx +103 -0
  55. package/templates/default/src/components/ui/carousel.tsx +242 -0
  56. package/templates/default/src/components/ui/chart.tsx +373 -0
  57. package/templates/default/src/components/ui/checkbox.tsx +33 -0
  58. package/templates/default/src/components/ui/collapsible.tsx +33 -0
  59. package/templates/default/src/components/ui/combobox.tsx +299 -0
  60. package/templates/default/src/components/ui/command.tsx +195 -0
  61. package/templates/default/src/components/ui/context-menu.tsx +263 -0
  62. package/templates/default/src/components/ui/dialog.tsx +168 -0
  63. package/templates/default/src/components/ui/direction.tsx +22 -0
  64. package/templates/default/src/components/ui/drawer.tsx +134 -0
  65. package/templates/default/src/components/ui/dropdown-menu.tsx +269 -0
  66. package/templates/default/src/components/ui/empty.tsx +104 -0
  67. package/templates/default/src/components/ui/field.tsx +238 -0
  68. package/templates/default/src/components/ui/hover-card.tsx +44 -0
  69. package/templates/default/src/components/ui/input-group.tsx +156 -0
  70. package/templates/default/src/components/ui/input-otp.tsx +87 -0
  71. package/templates/default/src/components/ui/input.tsx +19 -0
  72. package/templates/default/src/components/ui/item.tsx +196 -0
  73. package/templates/default/src/components/ui/kbd.tsx +26 -0
  74. package/templates/default/src/components/ui/label.tsx +24 -0
  75. package/templates/default/src/components/ui/menubar.tsx +280 -0
  76. package/templates/default/src/components/ui/native-select.tsx +52 -0
  77. package/templates/default/src/components/ui/navigation-menu.tsx +164 -0
  78. package/templates/default/src/components/ui/pagination.tsx +129 -0
  79. package/templates/default/src/components/ui/popover.tsx +89 -0
  80. package/templates/default/src/components/ui/progress.tsx +31 -0
  81. package/templates/default/src/components/ui/radio-group.tsx +44 -0
  82. package/templates/default/src/components/ui/resizable.tsx +50 -0
  83. package/templates/default/src/components/ui/scroll-area.tsx +55 -0
  84. package/templates/default/src/components/ui/select.tsx +192 -0
  85. package/templates/default/src/components/ui/separator.tsx +28 -0
  86. package/templates/default/src/components/ui/sheet.tsx +147 -0
  87. package/templates/default/src/components/ui/sidebar.tsx +702 -0
  88. package/templates/default/src/components/ui/skeleton.tsx +13 -0
  89. package/templates/default/src/components/ui/slider.tsx +59 -0
  90. package/templates/default/src/components/ui/sonner.tsx +49 -0
  91. package/templates/default/src/components/ui/spinner.tsx +10 -0
  92. package/templates/default/src/components/ui/switch.tsx +33 -0
  93. package/templates/default/src/components/ui/table.tsx +116 -0
  94. package/templates/default/src/components/ui/tabs.tsx +90 -0
  95. package/templates/default/src/components/ui/textarea.tsx +18 -0
  96. package/templates/default/src/components/ui/toggle-group.tsx +89 -0
  97. package/templates/default/src/components/ui/toggle.tsx +46 -0
  98. package/templates/default/src/components/ui/tooltip.tsx +57 -0
  99. package/templates/default/src/deesse.config.ts +11 -0
  100. package/templates/default/src/hooks/use-mobile.ts +19 -0
  101. package/templates/default/src/lib/utils.ts +6 -0
  102. package/templates/default/tsconfig.json +35 -0
  103. package/templates/minimal/.gitkeep +0 -0
@@ -0,0 +1,263 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { ContextMenu as ContextMenuPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { ChevronRightIcon, CheckIcon } from "lucide-react"
8
+
9
+ function ContextMenu({
10
+ ...props
11
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
12
+ return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />
13
+ }
14
+
15
+ function ContextMenuTrigger({
16
+ className,
17
+ ...props
18
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
19
+ return (
20
+ <ContextMenuPrimitive.Trigger
21
+ data-slot="context-menu-trigger"
22
+ className={cn("select-none", className)}
23
+ {...props}
24
+ />
25
+ )
26
+ }
27
+
28
+ function ContextMenuGroup({
29
+ ...props
30
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
31
+ return (
32
+ <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
33
+ )
34
+ }
35
+
36
+ function ContextMenuPortal({
37
+ ...props
38
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {
39
+ return (
40
+ <ContextMenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
41
+ )
42
+ }
43
+
44
+ function ContextMenuSub({
45
+ ...props
46
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Sub>) {
47
+ return <ContextMenuPrimitive.Sub data-slot="context-menu-sub" {...props} />
48
+ }
49
+
50
+ function ContextMenuRadioGroup({
51
+ ...props
52
+ }: React.ComponentProps<typeof ContextMenuPrimitive.RadioGroup>) {
53
+ return (
54
+ <ContextMenuPrimitive.RadioGroup
55
+ data-slot="context-menu-radio-group"
56
+ {...props}
57
+ />
58
+ )
59
+ }
60
+
61
+ function ContextMenuContent({
62
+ className,
63
+ ...props
64
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Content> & {
65
+ side?: "top" | "right" | "bottom" | "left"
66
+ }) {
67
+ return (
68
+ <ContextMenuPrimitive.Portal>
69
+ <ContextMenuPrimitive.Content
70
+ data-slot="context-menu-content"
71
+ className={cn("z-50 max-h-(--radix-context-menu-content-available-height) min-w-36 origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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 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 )}
72
+ {...props}
73
+ />
74
+ </ContextMenuPrimitive.Portal>
75
+ )
76
+ }
77
+
78
+ function ContextMenuItem({
79
+ className,
80
+ inset,
81
+ variant = "default",
82
+ ...props
83
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
84
+ inset?: boolean
85
+ variant?: "default" | "destructive"
86
+ }) {
87
+ return (
88
+ <ContextMenuPrimitive.Item
89
+ data-slot="context-menu-item"
90
+ data-inset={inset}
91
+ data-variant={variant}
92
+ className={cn(
93
+ "group/context-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 focus:*:[svg]:text-accent-foreground data-[variant=destructive]:*:[svg]:text-destructive",
94
+ className
95
+ )}
96
+ {...props}
97
+ />
98
+ )
99
+ }
100
+
101
+ function ContextMenuSubTrigger({
102
+ className,
103
+ inset,
104
+ children,
105
+ ...props
106
+ }: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {
107
+ inset?: boolean
108
+ }) {
109
+ return (
110
+ <ContextMenuPrimitive.SubTrigger
111
+ data-slot="context-menu-sub-trigger"
112
+ data-inset={inset}
113
+ className={cn(
114
+ "flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
115
+ className
116
+ )}
117
+ {...props}
118
+ >
119
+ {children}
120
+ <ChevronRightIcon className="ml-auto" />
121
+ </ContextMenuPrimitive.SubTrigger>
122
+ )
123
+ }
124
+
125
+ function ContextMenuSubContent({
126
+ className,
127
+ ...props
128
+ }: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {
129
+ return (
130
+ <ContextMenuPrimitive.SubContent
131
+ data-slot="context-menu-sub-content"
132
+ className={cn("z-50 min-w-32 origin-(--radix-context-menu-content-transform-origin) overflow-hidden rounded-lg border bg-popover p-1 text-popover-foreground shadow-lg duration-100 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 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 )}
133
+ {...props}
134
+ />
135
+ )
136
+ }
137
+
138
+ function ContextMenuCheckboxItem({
139
+ className,
140
+ children,
141
+ checked,
142
+ inset,
143
+ ...props
144
+ }: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem> & {
145
+ inset?: boolean
146
+ }) {
147
+ return (
148
+ <ContextMenuPrimitive.CheckboxItem
149
+ data-slot="context-menu-checkbox-item"
150
+ data-inset={inset}
151
+ className={cn(
152
+ "relative flex 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 data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
153
+ className
154
+ )}
155
+ checked={checked}
156
+ {...props}
157
+ >
158
+ <span className="pointer-events-none absolute right-2">
159
+ <ContextMenuPrimitive.ItemIndicator>
160
+ <CheckIcon
161
+ />
162
+ </ContextMenuPrimitive.ItemIndicator>
163
+ </span>
164
+ {children}
165
+ </ContextMenuPrimitive.CheckboxItem>
166
+ )
167
+ }
168
+
169
+ function ContextMenuRadioItem({
170
+ className,
171
+ children,
172
+ inset,
173
+ ...props
174
+ }: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem> & {
175
+ inset?: boolean
176
+ }) {
177
+ return (
178
+ <ContextMenuPrimitive.RadioItem
179
+ data-slot="context-menu-radio-item"
180
+ data-inset={inset}
181
+ className={cn(
182
+ "relative flex 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 data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
183
+ className
184
+ )}
185
+ {...props}
186
+ >
187
+ <span className="pointer-events-none absolute right-2">
188
+ <ContextMenuPrimitive.ItemIndicator>
189
+ <CheckIcon
190
+ />
191
+ </ContextMenuPrimitive.ItemIndicator>
192
+ </span>
193
+ {children}
194
+ </ContextMenuPrimitive.RadioItem>
195
+ )
196
+ }
197
+
198
+ function ContextMenuLabel({
199
+ className,
200
+ inset,
201
+ ...props
202
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
203
+ inset?: boolean
204
+ }) {
205
+ return (
206
+ <ContextMenuPrimitive.Label
207
+ data-slot="context-menu-label"
208
+ data-inset={inset}
209
+ className={cn(
210
+ "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7",
211
+ className
212
+ )}
213
+ {...props}
214
+ />
215
+ )
216
+ }
217
+
218
+ function ContextMenuSeparator({
219
+ className,
220
+ ...props
221
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {
222
+ return (
223
+ <ContextMenuPrimitive.Separator
224
+ data-slot="context-menu-separator"
225
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
226
+ {...props}
227
+ />
228
+ )
229
+ }
230
+
231
+ function ContextMenuShortcut({
232
+ className,
233
+ ...props
234
+ }: React.ComponentProps<"span">) {
235
+ return (
236
+ <span
237
+ data-slot="context-menu-shortcut"
238
+ className={cn(
239
+ "ml-auto text-xs tracking-widest text-muted-foreground group-focus/context-menu-item:text-accent-foreground",
240
+ className
241
+ )}
242
+ {...props}
243
+ />
244
+ )
245
+ }
246
+
247
+ export {
248
+ ContextMenu,
249
+ ContextMenuTrigger,
250
+ ContextMenuContent,
251
+ ContextMenuItem,
252
+ ContextMenuCheckboxItem,
253
+ ContextMenuRadioItem,
254
+ ContextMenuLabel,
255
+ ContextMenuSeparator,
256
+ ContextMenuShortcut,
257
+ ContextMenuGroup,
258
+ ContextMenuPortal,
259
+ ContextMenuSub,
260
+ ContextMenuSubContent,
261
+ ContextMenuSubTrigger,
262
+ ContextMenuRadioGroup,
263
+ }
@@ -0,0 +1,168 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Dialog as DialogPrimitive } from "radix-ui"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { Button } from "@/components/ui/button"
8
+ import { XIcon } from "lucide-react"
9
+
10
+ function Dialog({
11
+ ...props
12
+ }: React.ComponentProps<typeof DialogPrimitive.Root>) {
13
+ return <DialogPrimitive.Root data-slot="dialog" {...props} />
14
+ }
15
+
16
+ function DialogTrigger({
17
+ ...props
18
+ }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
19
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
20
+ }
21
+
22
+ function DialogPortal({
23
+ ...props
24
+ }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
25
+ return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
26
+ }
27
+
28
+ function DialogClose({
29
+ ...props
30
+ }: React.ComponentProps<typeof DialogPrimitive.Close>) {
31
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
32
+ }
33
+
34
+ function DialogOverlay({
35
+ className,
36
+ ...props
37
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
38
+ return (
39
+ <DialogPrimitive.Overlay
40
+ data-slot="dialog-overlay"
41
+ className={cn(
42
+ "fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
43
+ className
44
+ )}
45
+ {...props}
46
+ />
47
+ )
48
+ }
49
+
50
+ function DialogContent({
51
+ className,
52
+ children,
53
+ showCloseButton = true,
54
+ ...props
55
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
56
+ showCloseButton?: boolean
57
+ }) {
58
+ return (
59
+ <DialogPortal>
60
+ <DialogOverlay />
61
+ <DialogPrimitive.Content
62
+ data-slot="dialog-content"
63
+ className={cn(
64
+ "fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm 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",
65
+ className
66
+ )}
67
+ {...props}
68
+ >
69
+ {children}
70
+ {showCloseButton && (
71
+ <DialogPrimitive.Close data-slot="dialog-close" asChild>
72
+ <Button
73
+ variant="ghost"
74
+ className="absolute top-2 right-2"
75
+ size="icon-sm"
76
+ >
77
+ <XIcon
78
+ />
79
+ <span className="sr-only">Close</span>
80
+ </Button>
81
+ </DialogPrimitive.Close>
82
+ )}
83
+ </DialogPrimitive.Content>
84
+ </DialogPortal>
85
+ )
86
+ }
87
+
88
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
89
+ return (
90
+ <div
91
+ data-slot="dialog-header"
92
+ className={cn("flex flex-col gap-2", className)}
93
+ {...props}
94
+ />
95
+ )
96
+ }
97
+
98
+ function DialogFooter({
99
+ className,
100
+ showCloseButton = false,
101
+ children,
102
+ ...props
103
+ }: React.ComponentProps<"div"> & {
104
+ showCloseButton?: boolean
105
+ }) {
106
+ return (
107
+ <div
108
+ data-slot="dialog-footer"
109
+ className={cn(
110
+ "-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end",
111
+ className
112
+ )}
113
+ {...props}
114
+ >
115
+ {children}
116
+ {showCloseButton && (
117
+ <DialogPrimitive.Close asChild>
118
+ <Button variant="outline">Close</Button>
119
+ </DialogPrimitive.Close>
120
+ )}
121
+ </div>
122
+ )
123
+ }
124
+
125
+ function DialogTitle({
126
+ className,
127
+ ...props
128
+ }: React.ComponentProps<typeof DialogPrimitive.Title>) {
129
+ return (
130
+ <DialogPrimitive.Title
131
+ data-slot="dialog-title"
132
+ className={cn(
133
+ "font-heading text-base leading-none font-medium",
134
+ className
135
+ )}
136
+ {...props}
137
+ />
138
+ )
139
+ }
140
+
141
+ function DialogDescription({
142
+ className,
143
+ ...props
144
+ }: React.ComponentProps<typeof DialogPrimitive.Description>) {
145
+ return (
146
+ <DialogPrimitive.Description
147
+ data-slot="dialog-description"
148
+ className={cn(
149
+ "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
150
+ className
151
+ )}
152
+ {...props}
153
+ />
154
+ )
155
+ }
156
+
157
+ export {
158
+ Dialog,
159
+ DialogClose,
160
+ DialogContent,
161
+ DialogDescription,
162
+ DialogFooter,
163
+ DialogHeader,
164
+ DialogOverlay,
165
+ DialogPortal,
166
+ DialogTitle,
167
+ DialogTrigger,
168
+ }
@@ -0,0 +1,22 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Direction } from "radix-ui"
5
+
6
+ function DirectionProvider({
7
+ dir,
8
+ direction,
9
+ children,
10
+ }: React.ComponentProps<typeof Direction.DirectionProvider> & {
11
+ direction?: React.ComponentProps<typeof Direction.DirectionProvider>["dir"]
12
+ }) {
13
+ return (
14
+ <Direction.DirectionProvider dir={direction ?? dir}>
15
+ {children}
16
+ </Direction.DirectionProvider>
17
+ )
18
+ }
19
+
20
+ const useDirection = Direction.useDirection
21
+
22
+ export { DirectionProvider, useDirection }
@@ -0,0 +1,134 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+ import { Drawer as DrawerPrimitive } from "vaul"
5
+
6
+ import { cn } from "@/lib/utils"
7
+
8
+ function Drawer({
9
+ ...props
10
+ }: React.ComponentProps<typeof DrawerPrimitive.Root>) {
11
+ return <DrawerPrimitive.Root data-slot="drawer" {...props} />
12
+ }
13
+
14
+ function DrawerTrigger({
15
+ ...props
16
+ }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
17
+ return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
18
+ }
19
+
20
+ function DrawerPortal({
21
+ ...props
22
+ }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
23
+ return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
24
+ }
25
+
26
+ function DrawerClose({
27
+ ...props
28
+ }: React.ComponentProps<typeof DrawerPrimitive.Close>) {
29
+ return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
30
+ }
31
+
32
+ function DrawerOverlay({
33
+ className,
34
+ ...props
35
+ }: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
36
+ return (
37
+ <DrawerPrimitive.Overlay
38
+ data-slot="drawer-overlay"
39
+ className={cn(
40
+ "fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
41
+ className
42
+ )}
43
+ {...props}
44
+ />
45
+ )
46
+ }
47
+
48
+ function DrawerContent({
49
+ className,
50
+ children,
51
+ ...props
52
+ }: React.ComponentProps<typeof DrawerPrimitive.Content>) {
53
+ return (
54
+ <DrawerPortal data-slot="drawer-portal">
55
+ <DrawerOverlay />
56
+ <DrawerPrimitive.Content
57
+ data-slot="drawer-content"
58
+ className={cn(
59
+ "group/drawer-content fixed z-50 flex h-auto flex-col bg-popover text-sm text-popover-foreground data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-r-xl data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-l-xl data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm",
60
+ className
61
+ )}
62
+ {...props}
63
+ >
64
+ <div className="mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
65
+ {children}
66
+ </DrawerPrimitive.Content>
67
+ </DrawerPortal>
68
+ )
69
+ }
70
+
71
+ function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
72
+ return (
73
+ <div
74
+ data-slot="drawer-header"
75
+ className={cn(
76
+ "flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-left",
77
+ className
78
+ )}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
85
+ return (
86
+ <div
87
+ data-slot="drawer-footer"
88
+ className={cn("mt-auto flex flex-col gap-2 p-4", className)}
89
+ {...props}
90
+ />
91
+ )
92
+ }
93
+
94
+ function DrawerTitle({
95
+ className,
96
+ ...props
97
+ }: React.ComponentProps<typeof DrawerPrimitive.Title>) {
98
+ return (
99
+ <DrawerPrimitive.Title
100
+ data-slot="drawer-title"
101
+ className={cn(
102
+ "font-heading text-base font-medium text-foreground",
103
+ className
104
+ )}
105
+ {...props}
106
+ />
107
+ )
108
+ }
109
+
110
+ function DrawerDescription({
111
+ className,
112
+ ...props
113
+ }: React.ComponentProps<typeof DrawerPrimitive.Description>) {
114
+ return (
115
+ <DrawerPrimitive.Description
116
+ data-slot="drawer-description"
117
+ className={cn("text-sm text-muted-foreground", className)}
118
+ {...props}
119
+ />
120
+ )
121
+ }
122
+
123
+ export {
124
+ Drawer,
125
+ DrawerPortal,
126
+ DrawerOverlay,
127
+ DrawerTrigger,
128
+ DrawerClose,
129
+ DrawerContent,
130
+ DrawerHeader,
131
+ DrawerFooter,
132
+ DrawerTitle,
133
+ DrawerDescription,
134
+ }