create-ec-app 1.7.0 → 1.9.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 (104) hide show
  1. package/README.md +72 -17
  2. package/dist/cssScope.js +3 -5
  3. package/dist/cssScope.js.map +1 -1
  4. package/dist/index.d.ts +46 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +129 -53
  7. package/dist/index.js.map +1 -1
  8. package/dist/libFunctions.d.ts +13 -6
  9. package/dist/libFunctions.d.ts.map +1 -1
  10. package/dist/libFunctions.js +24 -9
  11. package/dist/libFunctions.js.map +1 -1
  12. package/dist/pcf.d.ts.map +1 -1
  13. package/dist/pcf.js +4 -1
  14. package/dist/pcf.js.map +1 -1
  15. package/dist/portalContainers.js +7 -5
  16. package/dist/portalContainers.js.map +1 -1
  17. package/package.json +18 -11
  18. package/scripts/build-generated.mjs +59 -0
  19. package/scripts/refresh-shadcn-template.ts +406 -0
  20. package/scripts/smoke-scaffold.mjs +245 -0
  21. package/templates/base/eslint.config.js +1 -1
  22. package/templates/base/package-lock.json +380 -476
  23. package/templates/base/package.json +14 -19
  24. package/templates/pcf/base/package-lock.json +35 -53
  25. package/templates/targets/code-apps/AGENTS.md +187 -0
  26. package/templates/targets/code-apps/CLAUDE.md +1 -0
  27. package/templates/targets/code-apps/package.patch.json +1 -1
  28. package/templates/targets/power-pages/AGENTS.md +192 -0
  29. package/templates/targets/power-pages/CLAUDE.md +1 -0
  30. package/templates/targets/power-pages/README.md +22 -2
  31. package/templates/targets/power-pages/src/App.patch.tsx +3 -1
  32. package/templates/targets/power-pages/src/components/shared/AuthError.tsx +18 -0
  33. package/templates/targets/power-pages/src/context/AuthContext.tsx +0 -4
  34. package/templates/targets/swa/AGENTS.md +181 -0
  35. package/templates/targets/swa/CLAUDE.md +1 -0
  36. package/templates/targets/webresource/AGENTS.md +179 -67
  37. package/templates/targets/webresource/CLAUDE.md +1 -0
  38. package/templates/targets/webresource/README.md +5 -5
  39. package/templates/ui/kendo/package.patch.json +2 -2
  40. package/templates/ui/shadcn-ui/SHADCN_TEMPLATE.md +20 -0
  41. package/templates/ui/shadcn-ui/package.patch.json +18 -9
  42. package/templates/ui/shadcn-ui/src/components/ui/accordion.tsx +79 -0
  43. package/templates/ui/shadcn-ui/src/components/ui/alert-dialog.tsx +199 -0
  44. package/templates/ui/shadcn-ui/src/components/ui/alert.tsx +76 -0
  45. package/templates/ui/shadcn-ui/src/components/ui/aspect-ratio.tsx +11 -0
  46. package/templates/ui/shadcn-ui/src/components/ui/attachment.tsx +206 -0
  47. package/templates/ui/shadcn-ui/src/components/ui/avatar.tsx +110 -0
  48. package/templates/ui/shadcn-ui/src/components/ui/badge.tsx +49 -0
  49. package/templates/ui/shadcn-ui/src/components/ui/breadcrumb.tsx +122 -0
  50. package/templates/ui/shadcn-ui/src/components/ui/bubble.tsx +125 -0
  51. package/templates/ui/shadcn-ui/src/components/ui/button-group.tsx +83 -0
  52. package/templates/ui/shadcn-ui/src/components/ui/button.tsx +67 -0
  53. package/templates/ui/shadcn-ui/src/components/ui/calendar.tsx +222 -0
  54. package/templates/ui/shadcn-ui/src/components/ui/card.tsx +103 -0
  55. package/templates/ui/shadcn-ui/src/components/ui/carousel.tsx +240 -0
  56. package/templates/ui/shadcn-ui/src/components/ui/chart.tsx +373 -0
  57. package/templates/ui/shadcn-ui/src/components/ui/checkbox.tsx +31 -0
  58. package/templates/ui/shadcn-ui/src/components/ui/collapsible.tsx +33 -0
  59. package/templates/ui/shadcn-ui/src/components/ui/combobox.tsx +299 -0
  60. package/templates/ui/shadcn-ui/src/components/ui/command.tsx +195 -0
  61. package/templates/ui/shadcn-ui/src/components/ui/context-menu.tsx +264 -0
  62. package/templates/ui/shadcn-ui/src/components/ui/dialog.tsx +170 -0
  63. package/templates/ui/shadcn-ui/src/components/ui/direction.tsx +22 -0
  64. package/templates/ui/shadcn-ui/src/components/ui/drawer.tsx +134 -0
  65. package/templates/ui/shadcn-ui/src/components/ui/dropdown-menu.tsx +272 -0
  66. package/templates/ui/shadcn-ui/src/components/ui/empty.tsx +104 -0
  67. package/templates/ui/shadcn-ui/src/components/ui/field.tsx +236 -0
  68. package/templates/ui/shadcn-ui/src/components/ui/hover-card.tsx +44 -0
  69. package/templates/ui/shadcn-ui/src/components/ui/input-group.tsx +156 -0
  70. package/templates/ui/shadcn-ui/src/components/ui/input-otp.tsx +87 -0
  71. package/templates/ui/shadcn-ui/src/components/ui/input.tsx +19 -0
  72. package/templates/ui/shadcn-ui/src/components/ui/item.tsx +196 -0
  73. package/templates/ui/shadcn-ui/src/components/ui/kbd.tsx +26 -0
  74. package/templates/ui/shadcn-ui/src/components/ui/label.tsx +22 -0
  75. package/templates/ui/shadcn-ui/src/components/ui/marker.tsx +69 -0
  76. package/templates/ui/shadcn-ui/src/components/ui/menubar.tsx +282 -0
  77. package/templates/ui/shadcn-ui/src/components/ui/message-scroller.tsx +129 -0
  78. package/templates/ui/shadcn-ui/src/components/ui/message.tsx +92 -0
  79. package/templates/ui/shadcn-ui/src/components/ui/native-select.tsx +61 -0
  80. package/templates/ui/shadcn-ui/src/components/ui/navigation-menu.tsx +164 -0
  81. package/templates/ui/shadcn-ui/src/components/ui/pagination.tsx +129 -0
  82. package/templates/ui/shadcn-ui/src/components/ui/popover.tsx +89 -0
  83. package/templates/ui/shadcn-ui/src/components/ui/progress.tsx +31 -0
  84. package/templates/ui/shadcn-ui/src/components/ui/radio-group.tsx +42 -0
  85. package/templates/ui/shadcn-ui/src/components/ui/resizable.tsx +50 -0
  86. package/templates/ui/shadcn-ui/src/components/ui/scroll-area.tsx +53 -0
  87. package/templates/ui/shadcn-ui/src/components/ui/select.tsx +194 -0
  88. package/templates/ui/shadcn-ui/src/components/ui/separator.tsx +26 -0
  89. package/templates/ui/shadcn-ui/src/components/ui/sheet.tsx +149 -0
  90. package/templates/ui/shadcn-ui/src/components/ui/sidebar.tsx +702 -0
  91. package/templates/ui/shadcn-ui/src/components/ui/skeleton.tsx +13 -0
  92. package/templates/ui/shadcn-ui/src/components/ui/slider.tsx +59 -0
  93. package/templates/ui/shadcn-ui/src/components/ui/sonner.tsx +47 -0
  94. package/templates/ui/shadcn-ui/src/components/ui/spinner.tsx +10 -0
  95. package/templates/ui/shadcn-ui/src/components/ui/switch.tsx +33 -0
  96. package/templates/ui/shadcn-ui/src/components/ui/table.tsx +114 -0
  97. package/templates/ui/shadcn-ui/src/components/ui/tabs.tsx +90 -0
  98. package/templates/ui/shadcn-ui/src/components/ui/textarea.tsx +18 -0
  99. package/templates/ui/shadcn-ui/src/components/ui/toggle-group.tsx +87 -0
  100. package/templates/ui/shadcn-ui/src/components/ui/toggle.tsx +45 -0
  101. package/templates/ui/shadcn-ui/src/components/ui/tooltip.tsx +59 -0
  102. package/templates/ui/shadcn-ui/src/index.patch.css +0 -118
  103. package/templates/ui/shadcn-ui/src/runtime/PortalContainer.ts +8 -0
  104. package/templates/base/biome.json +0 -54
@@ -0,0 +1,264 @@
1
+ import * as React from "react"
2
+ import { ContextMenu as ContextMenuPrimitive } from "radix-ui"
3
+
4
+ import { cn } from "@/lib/utils"
5
+ import { ChevronRightIcon, CheckIcon } from "lucide-react"
6
+ import { usePortalContainer } from "@/runtime/PortalContainer"
7
+
8
+ function ContextMenu({
9
+ ...props
10
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Root>) {
11
+ return <ContextMenuPrimitive.Root data-slot="context-menu" {...props} />
12
+ }
13
+
14
+ function ContextMenuTrigger({
15
+ className,
16
+ ...props
17
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Trigger>) {
18
+ return (
19
+ <ContextMenuPrimitive.Trigger
20
+ data-slot="context-menu-trigger"
21
+ className={cn("select-none", className)}
22
+ {...props}
23
+ />
24
+ )
25
+ }
26
+
27
+ function ContextMenuGroup({
28
+ ...props
29
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Group>) {
30
+ return (
31
+ <ContextMenuPrimitive.Group data-slot="context-menu-group" {...props} />
32
+ )
33
+ }
34
+
35
+ function ContextMenuPortal({
36
+ ...props
37
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Portal>) {
38
+ const portalContainer = usePortalContainer()
39
+ return (
40
+ <ContextMenuPrimitive.Portal container={portalContainer ?? undefined} 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
+ const portalContainer = usePortalContainer()
68
+ return (
69
+ <ContextMenuPrimitive.Portal container={portalContainer ?? undefined}>
70
+ <ContextMenuPrimitive.Content
71
+ data-slot="context-menu-content"
72
+ 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 )}
73
+ {...props}
74
+ />
75
+ </ContextMenuPrimitive.Portal>
76
+ )
77
+ }
78
+
79
+ function ContextMenuItem({
80
+ className,
81
+ inset,
82
+ variant = "default",
83
+ ...props
84
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Item> & {
85
+ inset?: boolean
86
+ variant?: "default" | "destructive"
87
+ }) {
88
+ return (
89
+ <ContextMenuPrimitive.Item
90
+ data-slot="context-menu-item"
91
+ data-inset={inset}
92
+ data-variant={variant}
93
+ className={cn(
94
+ "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",
95
+ className
96
+ )}
97
+ {...props}
98
+ />
99
+ )
100
+ }
101
+
102
+ function ContextMenuSubTrigger({
103
+ className,
104
+ inset,
105
+ children,
106
+ ...props
107
+ }: React.ComponentProps<typeof ContextMenuPrimitive.SubTrigger> & {
108
+ inset?: boolean
109
+ }) {
110
+ return (
111
+ <ContextMenuPrimitive.SubTrigger
112
+ data-slot="context-menu-sub-trigger"
113
+ data-inset={inset}
114
+ className={cn(
115
+ "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",
116
+ className
117
+ )}
118
+ {...props}
119
+ >
120
+ {children}
121
+ <ChevronRightIcon className="ml-auto" />
122
+ </ContextMenuPrimitive.SubTrigger>
123
+ )
124
+ }
125
+
126
+ function ContextMenuSubContent({
127
+ className,
128
+ ...props
129
+ }: React.ComponentProps<typeof ContextMenuPrimitive.SubContent>) {
130
+ return (
131
+ <ContextMenuPrimitive.SubContent
132
+ data-slot="context-menu-sub-content"
133
+ 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 )}
134
+ {...props}
135
+ />
136
+ )
137
+ }
138
+
139
+ function ContextMenuCheckboxItem({
140
+ className,
141
+ children,
142
+ checked,
143
+ inset,
144
+ ...props
145
+ }: React.ComponentProps<typeof ContextMenuPrimitive.CheckboxItem> & {
146
+ inset?: boolean
147
+ }) {
148
+ return (
149
+ <ContextMenuPrimitive.CheckboxItem
150
+ data-slot="context-menu-checkbox-item"
151
+ data-inset={inset}
152
+ className={cn(
153
+ "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",
154
+ className
155
+ )}
156
+ checked={checked}
157
+ {...props}
158
+ >
159
+ <span className="pointer-events-none absolute right-2">
160
+ <ContextMenuPrimitive.ItemIndicator>
161
+ <CheckIcon
162
+ />
163
+ </ContextMenuPrimitive.ItemIndicator>
164
+ </span>
165
+ {children}
166
+ </ContextMenuPrimitive.CheckboxItem>
167
+ )
168
+ }
169
+
170
+ function ContextMenuRadioItem({
171
+ className,
172
+ children,
173
+ inset,
174
+ ...props
175
+ }: React.ComponentProps<typeof ContextMenuPrimitive.RadioItem> & {
176
+ inset?: boolean
177
+ }) {
178
+ return (
179
+ <ContextMenuPrimitive.RadioItem
180
+ data-slot="context-menu-radio-item"
181
+ data-inset={inset}
182
+ className={cn(
183
+ "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",
184
+ className
185
+ )}
186
+ {...props}
187
+ >
188
+ <span className="pointer-events-none absolute right-2">
189
+ <ContextMenuPrimitive.ItemIndicator>
190
+ <CheckIcon
191
+ />
192
+ </ContextMenuPrimitive.ItemIndicator>
193
+ </span>
194
+ {children}
195
+ </ContextMenuPrimitive.RadioItem>
196
+ )
197
+ }
198
+
199
+ function ContextMenuLabel({
200
+ className,
201
+ inset,
202
+ ...props
203
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Label> & {
204
+ inset?: boolean
205
+ }) {
206
+ return (
207
+ <ContextMenuPrimitive.Label
208
+ data-slot="context-menu-label"
209
+ data-inset={inset}
210
+ className={cn(
211
+ "px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7",
212
+ className
213
+ )}
214
+ {...props}
215
+ />
216
+ )
217
+ }
218
+
219
+ function ContextMenuSeparator({
220
+ className,
221
+ ...props
222
+ }: React.ComponentProps<typeof ContextMenuPrimitive.Separator>) {
223
+ return (
224
+ <ContextMenuPrimitive.Separator
225
+ data-slot="context-menu-separator"
226
+ className={cn("-mx-1 my-1 h-px bg-border", className)}
227
+ {...props}
228
+ />
229
+ )
230
+ }
231
+
232
+ function ContextMenuShortcut({
233
+ className,
234
+ ...props
235
+ }: React.ComponentProps<"span">) {
236
+ return (
237
+ <span
238
+ data-slot="context-menu-shortcut"
239
+ className={cn(
240
+ "ml-auto text-xs tracking-widest text-muted-foreground group-focus/context-menu-item:text-accent-foreground",
241
+ className
242
+ )}
243
+ {...props}
244
+ />
245
+ )
246
+ }
247
+
248
+ export {
249
+ ContextMenu,
250
+ ContextMenuTrigger,
251
+ ContextMenuContent,
252
+ ContextMenuItem,
253
+ ContextMenuCheckboxItem,
254
+ ContextMenuRadioItem,
255
+ ContextMenuLabel,
256
+ ContextMenuSeparator,
257
+ ContextMenuShortcut,
258
+ ContextMenuGroup,
259
+ ContextMenuPortal,
260
+ ContextMenuSub,
261
+ ContextMenuSubContent,
262
+ ContextMenuSubTrigger,
263
+ ContextMenuRadioGroup,
264
+ }
@@ -0,0 +1,170 @@
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
+ import { usePortalContainer } from "@/runtime/PortalContainer"
10
+
11
+ function Dialog({
12
+ ...props
13
+ }: React.ComponentProps<typeof DialogPrimitive.Root>) {
14
+ return <DialogPrimitive.Root data-slot="dialog" {...props} />
15
+ }
16
+
17
+ function DialogTrigger({
18
+ ...props
19
+ }: React.ComponentProps<typeof DialogPrimitive.Trigger>) {
20
+ return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
21
+ }
22
+
23
+ function DialogPortal({
24
+ ...props
25
+ }: React.ComponentProps<typeof DialogPrimitive.Portal>) {
26
+ const portalContainer = usePortalContainer()
27
+ return <DialogPrimitive.Portal container={portalContainer ?? undefined} data-slot="dialog-portal" {...props} />
28
+ }
29
+
30
+ function DialogClose({
31
+ ...props
32
+ }: React.ComponentProps<typeof DialogPrimitive.Close>) {
33
+ return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
34
+ }
35
+
36
+ function DialogOverlay({
37
+ className,
38
+ ...props
39
+ }: React.ComponentProps<typeof DialogPrimitive.Overlay>) {
40
+ return (
41
+ <DialogPrimitive.Overlay
42
+ data-slot="dialog-overlay"
43
+ className={cn(
44
+ "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",
45
+ className
46
+ )}
47
+ {...props}
48
+ />
49
+ )
50
+ }
51
+
52
+ function DialogContent({
53
+ className,
54
+ children,
55
+ showCloseButton = true,
56
+ ...props
57
+ }: React.ComponentProps<typeof DialogPrimitive.Content> & {
58
+ showCloseButton?: boolean
59
+ }) {
60
+ return (
61
+ <DialogPortal>
62
+ <DialogOverlay />
63
+ <DialogPrimitive.Content
64
+ data-slot="dialog-content"
65
+ className={cn(
66
+ "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",
67
+ className
68
+ )}
69
+ {...props}
70
+ >
71
+ {children}
72
+ {showCloseButton && (
73
+ <DialogPrimitive.Close data-slot="dialog-close" asChild>
74
+ <Button
75
+ variant="ghost"
76
+ className="absolute top-2 right-2"
77
+ size="icon-sm"
78
+ >
79
+ <XIcon
80
+ />
81
+ <span className="sr-only">Close</span>
82
+ </Button>
83
+ </DialogPrimitive.Close>
84
+ )}
85
+ </DialogPrimitive.Content>
86
+ </DialogPortal>
87
+ )
88
+ }
89
+
90
+ function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
91
+ return (
92
+ <div
93
+ data-slot="dialog-header"
94
+ className={cn("flex flex-col gap-2", className)}
95
+ {...props}
96
+ />
97
+ )
98
+ }
99
+
100
+ function DialogFooter({
101
+ className,
102
+ showCloseButton = false,
103
+ children,
104
+ ...props
105
+ }: React.ComponentProps<"div"> & {
106
+ showCloseButton?: boolean
107
+ }) {
108
+ return (
109
+ <div
110
+ data-slot="dialog-footer"
111
+ className={cn(
112
+ "-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",
113
+ className
114
+ )}
115
+ {...props}
116
+ >
117
+ {children}
118
+ {showCloseButton && (
119
+ <DialogPrimitive.Close asChild>
120
+ <Button variant="outline">Close</Button>
121
+ </DialogPrimitive.Close>
122
+ )}
123
+ </div>
124
+ )
125
+ }
126
+
127
+ function DialogTitle({
128
+ className,
129
+ ...props
130
+ }: React.ComponentProps<typeof DialogPrimitive.Title>) {
131
+ return (
132
+ <DialogPrimitive.Title
133
+ data-slot="dialog-title"
134
+ className={cn(
135
+ "text-base leading-none font-medium",
136
+ className
137
+ )}
138
+ {...props}
139
+ />
140
+ )
141
+ }
142
+
143
+ function DialogDescription({
144
+ className,
145
+ ...props
146
+ }: React.ComponentProps<typeof DialogPrimitive.Description>) {
147
+ return (
148
+ <DialogPrimitive.Description
149
+ data-slot="dialog-description"
150
+ className={cn(
151
+ "text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
152
+ className
153
+ )}
154
+ {...props}
155
+ />
156
+ )
157
+ }
158
+
159
+ export {
160
+ Dialog,
161
+ DialogClose,
162
+ DialogContent,
163
+ DialogDescription,
164
+ DialogFooter,
165
+ DialogHeader,
166
+ DialogOverlay,
167
+ DialogPortal,
168
+ DialogTitle,
169
+ DialogTrigger,
170
+ }
@@ -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
+ import * as React from "react"
2
+ import { Drawer as DrawerPrimitive } from "vaul"
3
+
4
+ import { cn } from "@/lib/utils"
5
+ import { usePortalContainer } from "@/runtime/PortalContainer"
6
+
7
+ function Drawer({
8
+ ...props
9
+ }: React.ComponentProps<typeof DrawerPrimitive.Root>) {
10
+ return <DrawerPrimitive.Root data-slot="drawer" {...props} />
11
+ }
12
+
13
+ function DrawerTrigger({
14
+ ...props
15
+ }: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
16
+ return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
17
+ }
18
+
19
+ function DrawerPortal({
20
+ ...props
21
+ }: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
22
+ const portalContainer = usePortalContainer()
23
+ return <DrawerPrimitive.Portal container={portalContainer ?? undefined} 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
+ "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
+ }