create-bdpamke-react-scaffold 1.0.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 (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/bin/create-bdpamke-react-scaffold.js +101 -0
  4. package/package.json +39 -0
  5. package/template/.env.example +6 -0
  6. package/template/FUNCTIONS_EXAMPLES.md +480 -0
  7. package/template/HOWTOadd a page.md +166 -0
  8. package/template/REACT_PROPS_USEEFFECT.md +210 -0
  9. package/template/REGISTRATION_FLOW.md +268 -0
  10. package/template/USESTATE_EXAMPLES.md +451 -0
  11. package/template/components.json +20 -0
  12. package/template/index.html +13 -0
  13. package/template/jsconfig.json +19 -0
  14. package/template/package-lock.json +5988 -0
  15. package/template/package.json +73 -0
  16. package/template/postcss.config.cjs +6 -0
  17. package/template/public/images/BDPA_edited.png +0 -0
  18. package/template/server/server.js +86 -0
  19. package/template/server/utils/apiClient.js +59 -0
  20. package/template/server/utils/password.js +60 -0
  21. package/template/src/App.jsx +10 -0
  22. package/template/src/components/layout/Container.jsx +7 -0
  23. package/template/src/components/layout/Section.jsx +7 -0
  24. package/template/src/components/ui/accordion.jsx +41 -0
  25. package/template/src/components/ui/alert-dialog.jsx +99 -0
  26. package/template/src/components/ui/alert.jsx +47 -0
  27. package/template/src/components/ui/aspect-ratio.jsx +5 -0
  28. package/template/src/components/ui/avatar.jsx +35 -0
  29. package/template/src/components/ui/badge.jsx +34 -0
  30. package/template/src/components/ui/button.jsx +47 -0
  31. package/template/src/components/ui/calendar.jsx +173 -0
  32. package/template/src/components/ui/card.jsx +50 -0
  33. package/template/src/components/ui/carousel.jsx +194 -0
  34. package/template/src/components/ui/checkbox.jsx +22 -0
  35. package/template/src/components/ui/collapsible.jsx +11 -0
  36. package/template/src/components/ui/command.jsx +116 -0
  37. package/template/src/components/ui/dialog.jsx +94 -0
  38. package/template/src/components/ui/drawer.jsx +92 -0
  39. package/template/src/components/ui/dropdown-menu.jsx +155 -0
  40. package/template/src/components/ui/form.jsx +138 -0
  41. package/template/src/components/ui/hover-card.jsx +25 -0
  42. package/template/src/components/ui/icons.jsx +81 -0
  43. package/template/src/components/ui/input.jsx +19 -0
  44. package/template/src/components/ui/label.jsx +16 -0
  45. package/template/src/components/ui/menubar.jsx +200 -0
  46. package/template/src/components/ui/navigation-menu.jsx +104 -0
  47. package/template/src/components/ui/popover.jsx +25 -0
  48. package/template/src/components/ui/progress.jsx +20 -0
  49. package/template/src/components/ui/radio-group.jsx +29 -0
  50. package/template/src/components/ui/scroll-area.jsx +40 -0
  51. package/template/src/components/ui/select.jsx +120 -0
  52. package/template/src/components/ui/separator.jsx +25 -0
  53. package/template/src/components/ui/sheet.jsx +108 -0
  54. package/template/src/components/ui/skeleton.jsx +10 -0
  55. package/template/src/components/ui/slider.jsx +23 -0
  56. package/template/src/components/ui/sonner.jsx +42 -0
  57. package/template/src/components/ui/switch.jsx +24 -0
  58. package/template/src/components/ui/table.jsx +83 -0
  59. package/template/src/components/ui/tabs.jsx +41 -0
  60. package/template/src/components/ui/textarea.jsx +18 -0
  61. package/template/src/components/ui/toast.jsx +82 -0
  62. package/template/src/components/ui/toaster.jsx +33 -0
  63. package/template/src/components/ui/toggle.jsx +40 -0
  64. package/template/src/components/ui/tooltip.jsx +24 -0
  65. package/template/src/hooks/use-toast.js +155 -0
  66. package/template/src/index.css +61 -0
  67. package/template/src/index.js +6 -0
  68. package/template/src/lib/utils.js +11 -0
  69. package/template/src/main.jsx +15 -0
  70. package/template/src/pages/Home.jsx +26 -0
  71. package/template/tailwind.config.cjs +76 -0
  72. package/template/vite.config.mts +22 -0
@@ -0,0 +1,173 @@
1
+ import * as React from "react"
2
+ import {
3
+ ChevronDownIcon,
4
+ ChevronLeftIcon,
5
+ ChevronRightIcon,
6
+ } from "lucide-react"
7
+ import { DayPicker, getDefaultClassNames } from "react-day-picker";
8
+
9
+ import { cn } from "@/lib/utils"
10
+ import { Button, buttonVariants } from "@/components/ui/button"
11
+
12
+ function Calendar({
13
+ className,
14
+ classNames,
15
+ showOutsideDays = true,
16
+ captionLayout = "label",
17
+ buttonVariant = "ghost",
18
+ formatters,
19
+ components,
20
+ ...props
21
+ }) {
22
+ const defaultClassNames = getDefaultClassNames()
23
+
24
+ return (
25
+ <DayPicker
26
+ showOutsideDays={showOutsideDays}
27
+ className={cn(
28
+ "bg-background group/calendar p-3 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
29
+ String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
30
+ String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
31
+ className
32
+ )}
33
+ captionLayout={captionLayout}
34
+ formatters={{
35
+ formatMonthDropdown: (date) =>
36
+ date.toLocaleString("default", { month: "short" }),
37
+ ...formatters,
38
+ }}
39
+ classNames={{
40
+ root: cn("w-fit", defaultClassNames.root),
41
+ months: cn("relative flex flex-col gap-4 md:flex-row", defaultClassNames.months),
42
+ month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
43
+ nav: cn(
44
+ "absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1",
45
+ defaultClassNames.nav
46
+ ),
47
+ button_previous: cn(
48
+ buttonVariants({ variant: buttonVariant }),
49
+ "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
50
+ defaultClassNames.button_previous
51
+ ),
52
+ button_next: cn(
53
+ buttonVariants({ variant: buttonVariant }),
54
+ "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
55
+ defaultClassNames.button_next
56
+ ),
57
+ month_caption: cn(
58
+ "flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",
59
+ defaultClassNames.month_caption
60
+ ),
61
+ dropdowns: cn(
62
+ "flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",
63
+ defaultClassNames.dropdowns
64
+ ),
65
+ dropdown_root: cn(
66
+ "has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",
67
+ defaultClassNames.dropdown_root
68
+ ),
69
+ dropdown: cn("bg-popover absolute inset-0 opacity-0", defaultClassNames.dropdown),
70
+ caption_label: cn("select-none font-medium", captionLayout === "label"
71
+ ? "text-sm"
72
+ : "[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5", defaultClassNames.caption_label),
73
+ table: "w-full border-collapse",
74
+ weekdays: cn("flex", defaultClassNames.weekdays),
75
+ weekday: cn(
76
+ "text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",
77
+ defaultClassNames.weekday
78
+ ),
79
+ week: cn("mt-2 flex w-full", defaultClassNames.week),
80
+ week_number_header: cn("w-[--cell-size] select-none", defaultClassNames.week_number_header),
81
+ week_number: cn(
82
+ "text-muted-foreground select-none text-[0.8rem]",
83
+ defaultClassNames.week_number
84
+ ),
85
+ day: cn(
86
+ "group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",
87
+ defaultClassNames.day
88
+ ),
89
+ range_start: cn("bg-accent rounded-l-md", defaultClassNames.range_start),
90
+ range_middle: cn("rounded-none", defaultClassNames.range_middle),
91
+ range_end: cn("bg-accent rounded-r-md", defaultClassNames.range_end),
92
+ today: cn(
93
+ "bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
94
+ defaultClassNames.today
95
+ ),
96
+ outside: cn(
97
+ "text-muted-foreground aria-selected:text-muted-foreground",
98
+ defaultClassNames.outside
99
+ ),
100
+ disabled: cn("text-muted-foreground opacity-50", defaultClassNames.disabled),
101
+ hidden: cn("invisible", defaultClassNames.hidden),
102
+ ...classNames,
103
+ }}
104
+ components={{
105
+ Root: ({ className, rootRef, ...props }) => {
106
+ return (<div data-slot="calendar" ref={rootRef} className={cn(className)} {...props} />);
107
+ },
108
+ Chevron: ({ className, orientation, ...props }) => {
109
+ if (orientation === "left") {
110
+ return (<ChevronLeftIcon className={cn("size-4", className)} {...props} />);
111
+ }
112
+
113
+ if (orientation === "right") {
114
+ return (<ChevronRightIcon className={cn("size-4", className)} {...props} />);
115
+ }
116
+
117
+ return (<ChevronDownIcon className={cn("size-4", className)} {...props} />);
118
+ },
119
+ DayButton: CalendarDayButton,
120
+ WeekNumber: ({ children, ...props }) => {
121
+ return (
122
+ <td {...props}>
123
+ <div
124
+ className="flex size-[--cell-size] items-center justify-center text-center">
125
+ {children}
126
+ </div>
127
+ </td>
128
+ );
129
+ },
130
+ ...components,
131
+ }}
132
+ {...props} />
133
+ );
134
+ }
135
+
136
+ function CalendarDayButton({
137
+ className,
138
+ day,
139
+ modifiers,
140
+ ...props
141
+ }) {
142
+ const defaultClassNames = getDefaultClassNames()
143
+
144
+ const ref = React.useRef(null)
145
+ React.useEffect(() => {
146
+ if (modifiers.focused) ref.current?.focus()
147
+ }, [modifiers.focused])
148
+
149
+ return (
150
+ <Button
151
+ ref={ref}
152
+ variant="ghost"
153
+ size="icon"
154
+ data-day={day.date.toLocaleDateString()}
155
+ data-selected-single={
156
+ modifiers.selected &&
157
+ !modifiers.range_start &&
158
+ !modifiers.range_end &&
159
+ !modifiers.range_middle
160
+ }
161
+ data-range-start={modifiers.range_start}
162
+ data-range-end={modifiers.range_end}
163
+ data-range-middle={modifiers.range_middle}
164
+ className={cn(
165
+ "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70",
166
+ defaultClassNames.day,
167
+ className
168
+ )}
169
+ {...props} />
170
+ );
171
+ }
172
+
173
+ export { Calendar, CalendarDayButton }
@@ -0,0 +1,50 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ const Card = React.forwardRef(({ className, ...props }, ref) => (
6
+ <div
7
+ ref={ref}
8
+ className={cn("rounded-lg border bg-card text-card-foreground shadow-sm", className)}
9
+ {...props} />
10
+ ))
11
+ Card.displayName = "Card"
12
+
13
+ const CardHeader = React.forwardRef(({ className, ...props }, ref) => (
14
+ <div
15
+ ref={ref}
16
+ className={cn("flex flex-col space-y-1.5 p-6", className)}
17
+ {...props} />
18
+ ))
19
+ CardHeader.displayName = "CardHeader"
20
+
21
+ const CardTitle = React.forwardRef(({ className, ...props }, ref) => (
22
+ <div
23
+ ref={ref}
24
+ className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
25
+ {...props} />
26
+ ))
27
+ CardTitle.displayName = "CardTitle"
28
+
29
+ const CardDescription = React.forwardRef(({ className, ...props }, ref) => (
30
+ <div
31
+ ref={ref}
32
+ className={cn("text-sm text-muted-foreground", className)}
33
+ {...props} />
34
+ ))
35
+ CardDescription.displayName = "CardDescription"
36
+
37
+ const CardContent = React.forwardRef(({ className, ...props }, ref) => (
38
+ <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
39
+ ))
40
+ CardContent.displayName = "CardContent"
41
+
42
+ const CardFooter = React.forwardRef(({ className, ...props }, ref) => (
43
+ <div
44
+ ref={ref}
45
+ className={cn("flex items-center p-6 pt-0", className)}
46
+ {...props} />
47
+ ))
48
+ CardFooter.displayName = "CardFooter"
49
+
50
+ export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
@@ -0,0 +1,194 @@
1
+ "use client";
2
+ import * as React from "react"
3
+ import useEmblaCarousel from "embla-carousel-react";
4
+ import { ArrowLeft, ArrowRight } from "lucide-react"
5
+
6
+ import { cn } from "@/lib/utils"
7
+ import { Button } from "@/components/ui/button"
8
+
9
+ const CarouselContext = React.createContext(null)
10
+
11
+ function useCarousel() {
12
+ const context = React.useContext(CarouselContext)
13
+
14
+ if (!context) {
15
+ throw new Error("useCarousel must be used within a <Carousel />")
16
+ }
17
+
18
+ return context
19
+ }
20
+
21
+ const Carousel = React.forwardRef((
22
+ {
23
+ orientation = "horizontal",
24
+ opts,
25
+ setApi,
26
+ plugins,
27
+ className,
28
+ children,
29
+ ...props
30
+ },
31
+ ref
32
+ ) => {
33
+ const [carouselRef, api] = useEmblaCarousel({
34
+ ...opts,
35
+ axis: orientation === "horizontal" ? "x" : "y",
36
+ }, plugins)
37
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false)
38
+ const [canScrollNext, setCanScrollNext] = React.useState(false)
39
+
40
+ const onSelect = React.useCallback((api) => {
41
+ if (!api) {
42
+ return
43
+ }
44
+
45
+ setCanScrollPrev(api.canScrollPrev())
46
+ setCanScrollNext(api.canScrollNext())
47
+ }, [])
48
+
49
+ const scrollPrev = React.useCallback(() => {
50
+ api?.scrollPrev()
51
+ }, [api])
52
+
53
+ const scrollNext = React.useCallback(() => {
54
+ api?.scrollNext()
55
+ }, [api])
56
+
57
+ const handleKeyDown = React.useCallback((event) => {
58
+ if (event.key === "ArrowLeft") {
59
+ event.preventDefault()
60
+ scrollPrev()
61
+ } else if (event.key === "ArrowRight") {
62
+ event.preventDefault()
63
+ scrollNext()
64
+ }
65
+ }, [scrollPrev, scrollNext])
66
+
67
+ React.useEffect(() => {
68
+ if (!api || !setApi) {
69
+ return
70
+ }
71
+
72
+ setApi(api)
73
+ }, [api, setApi])
74
+
75
+ React.useEffect(() => {
76
+ if (!api) {
77
+ return
78
+ }
79
+
80
+ onSelect(api)
81
+ api.on("reInit", onSelect)
82
+ api.on("select", onSelect)
83
+
84
+ return () => {
85
+ api?.off("select", onSelect)
86
+ };
87
+ }, [api, onSelect])
88
+
89
+ return (
90
+ <CarouselContext.Provider
91
+ value={{
92
+ carouselRef,
93
+ api: api,
94
+ opts,
95
+ orientation:
96
+ orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
97
+ scrollPrev,
98
+ scrollNext,
99
+ canScrollPrev,
100
+ canScrollNext,
101
+ }}>
102
+ <div
103
+ ref={ref}
104
+ onKeyDownCapture={handleKeyDown}
105
+ className={cn("relative", className)}
106
+ role="region"
107
+ aria-roledescription="carousel"
108
+ {...props}>
109
+ {children}
110
+ </div>
111
+ </CarouselContext.Provider>
112
+ );
113
+ })
114
+ Carousel.displayName = "Carousel"
115
+
116
+ const CarouselContent = React.forwardRef(({ className, ...props }, ref) => {
117
+ const { carouselRef, orientation } = useCarousel()
118
+
119
+ return (
120
+ <div ref={carouselRef} className="overflow-hidden">
121
+ <div
122
+ ref={ref}
123
+ className={cn(
124
+ "flex",
125
+ orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
126
+ className
127
+ )}
128
+ {...props} />
129
+ </div>
130
+ );
131
+ })
132
+ CarouselContent.displayName = "CarouselContent"
133
+
134
+ const CarouselItem = React.forwardRef(({ className, ...props }, ref) => {
135
+ const { orientation } = useCarousel()
136
+
137
+ return (
138
+ <div
139
+ ref={ref}
140
+ role="group"
141
+ aria-roledescription="slide"
142
+ className={cn(
143
+ "min-w-0 shrink-0 grow-0 basis-full",
144
+ orientation === "horizontal" ? "pl-4" : "pt-4",
145
+ className
146
+ )}
147
+ {...props} />
148
+ );
149
+ })
150
+ CarouselItem.displayName = "CarouselItem"
151
+
152
+ const CarouselPrevious = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
153
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel()
154
+
155
+ return (
156
+ <Button
157
+ ref={ref}
158
+ variant={variant}
159
+ size={size}
160
+ className={cn("absolute h-8 w-8 rounded-full", orientation === "horizontal"
161
+ ? "-left-12 top-1/2 -translate-y-1/2"
162
+ : "-top-12 left-1/2 -translate-x-1/2 rotate-90", className)}
163
+ disabled={!canScrollPrev}
164
+ onClick={scrollPrev}
165
+ {...props}>
166
+ <ArrowLeft className="h-4 w-4" />
167
+ <span className="sr-only">Previous slide</span>
168
+ </Button>
169
+ );
170
+ })
171
+ CarouselPrevious.displayName = "CarouselPrevious"
172
+
173
+ const CarouselNext = React.forwardRef(({ className, variant = "outline", size = "icon", ...props }, ref) => {
174
+ const { orientation, scrollNext, canScrollNext } = useCarousel()
175
+
176
+ return (
177
+ <Button
178
+ ref={ref}
179
+ variant={variant}
180
+ size={size}
181
+ className={cn("absolute h-8 w-8 rounded-full", orientation === "horizontal"
182
+ ? "-right-12 top-1/2 -translate-y-1/2"
183
+ : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90", className)}
184
+ disabled={!canScrollNext}
185
+ onClick={scrollNext}
186
+ {...props}>
187
+ <ArrowRight className="h-4 w-4" />
188
+ <span className="sr-only">Next slide</span>
189
+ </Button>
190
+ );
191
+ })
192
+ CarouselNext.displayName = "CarouselNext"
193
+
194
+ export { Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext };
@@ -0,0 +1,22 @@
1
+ import * as React from "react"
2
+ import * as CheckboxPrimitive from "@radix-ui/react-checkbox"
3
+ import { Check } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Checkbox = React.forwardRef(({ className, ...props }, ref) => (
8
+ <CheckboxPrimitive.Root
9
+ ref={ref}
10
+ className={cn(
11
+ "grid place-content-center peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
12
+ className
13
+ )}
14
+ {...props}>
15
+ <CheckboxPrimitive.Indicator className={cn("grid place-content-center text-current")}>
16
+ <Check className="h-4 w-4" />
17
+ </CheckboxPrimitive.Indicator>
18
+ </CheckboxPrimitive.Root>
19
+ ))
20
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName
21
+
22
+ export { Checkbox }
@@ -0,0 +1,11 @@
1
+ "use client"
2
+
3
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
4
+
5
+ const Collapsible = CollapsiblePrimitive.Root
6
+
7
+ const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger
8
+
9
+ const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent
10
+
11
+ export { Collapsible, CollapsibleTrigger, CollapsibleContent }
@@ -0,0 +1,116 @@
1
+ import * as React from "react"
2
+ import { Command as CommandPrimitive } from "cmdk"
3
+ import { Search } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+ import { Dialog, DialogContent } from "@/components/ui/dialog"
7
+
8
+ const Command = React.forwardRef(({ className, ...props }, ref) => (
9
+ <CommandPrimitive
10
+ ref={ref}
11
+ className={cn(
12
+ "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
13
+ className
14
+ )}
15
+ {...props} />
16
+ ))
17
+ Command.displayName = CommandPrimitive.displayName
18
+
19
+ const CommandDialog = ({
20
+ children,
21
+ ...props
22
+ }) => {
23
+ return (
24
+ <Dialog {...props}>
25
+ <DialogContent className="overflow-hidden p-0 shadow-lg">
26
+ <Command
27
+ className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
28
+ {children}
29
+ </Command>
30
+ </DialogContent>
31
+ </Dialog>
32
+ );
33
+ }
34
+
35
+ const CommandInput = React.forwardRef(({ className, ...props }, ref) => (
36
+ <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
37
+ <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
38
+ <CommandPrimitive.Input
39
+ ref={ref}
40
+ className={cn(
41
+ "flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
42
+ className
43
+ )}
44
+ {...props} />
45
+ </div>
46
+ ))
47
+
48
+ CommandInput.displayName = CommandPrimitive.Input.displayName
49
+
50
+ const CommandList = React.forwardRef(({ className, ...props }, ref) => (
51
+ <CommandPrimitive.List
52
+ ref={ref}
53
+ className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
54
+ {...props} />
55
+ ))
56
+
57
+ CommandList.displayName = CommandPrimitive.List.displayName
58
+
59
+ const CommandEmpty = React.forwardRef((props, ref) => (
60
+ <CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props} />
61
+ ))
62
+
63
+ CommandEmpty.displayName = CommandPrimitive.Empty.displayName
64
+
65
+ const CommandGroup = React.forwardRef(({ className, ...props }, ref) => (
66
+ <CommandPrimitive.Group
67
+ ref={ref}
68
+ className={cn(
69
+ "overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
70
+ className
71
+ )}
72
+ {...props} />
73
+ ))
74
+
75
+ CommandGroup.displayName = CommandPrimitive.Group.displayName
76
+
77
+ const CommandSeparator = React.forwardRef(({ className, ...props }, ref) => (
78
+ <CommandPrimitive.Separator ref={ref} className={cn("-mx-1 h-px bg-border", className)} {...props} />
79
+ ))
80
+ CommandSeparator.displayName = CommandPrimitive.Separator.displayName
81
+
82
+ const CommandItem = React.forwardRef(({ className, ...props }, ref) => (
83
+ <CommandPrimitive.Item
84
+ ref={ref}
85
+ className={cn(
86
+ "relative flex cursor-default gap-2 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[selected='true']:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
87
+ className
88
+ )}
89
+ {...props} />
90
+ ))
91
+
92
+ CommandItem.displayName = CommandPrimitive.Item.displayName
93
+
94
+ const CommandShortcut = ({
95
+ className,
96
+ ...props
97
+ }) => {
98
+ return (
99
+ <span
100
+ className={cn("ml-auto text-xs tracking-widest text-muted-foreground", className)}
101
+ {...props} />
102
+ );
103
+ }
104
+ CommandShortcut.displayName = "CommandShortcut"
105
+
106
+ export {
107
+ Command,
108
+ CommandDialog,
109
+ CommandInput,
110
+ CommandList,
111
+ CommandEmpty,
112
+ CommandGroup,
113
+ CommandItem,
114
+ CommandShortcut,
115
+ CommandSeparator,
116
+ }
@@ -0,0 +1,94 @@
1
+ import * as React from "react"
2
+ import * as DialogPrimitive from "@radix-ui/react-dialog"
3
+ import { X } from "lucide-react"
4
+
5
+ import { cn } from "@/lib/utils"
6
+
7
+ const Dialog = DialogPrimitive.Root
8
+
9
+ const DialogTrigger = DialogPrimitive.Trigger
10
+
11
+ const DialogPortal = DialogPrimitive.Portal
12
+
13
+ const DialogClose = DialogPrimitive.Close
14
+
15
+ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (
16
+ <DialogPrimitive.Overlay
17
+ ref={ref}
18
+ className={cn(
19
+ "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
20
+ className
21
+ )}
22
+ {...props} />
23
+ ))
24
+ DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
25
+
26
+ const DialogContent = React.forwardRef(({ className, children, ...props }, ref) => (
27
+ <DialogPortal>
28
+ <DialogOverlay />
29
+ <DialogPrimitive.Content
30
+ ref={ref}
31
+ className={cn(
32
+ "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
33
+ className
34
+ )}
35
+ {...props}>
36
+ {children}
37
+ <DialogPrimitive.Close
38
+ className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
39
+ <X className="h-4 w-4" />
40
+ <span className="sr-only">Close</span>
41
+ </DialogPrimitive.Close>
42
+ </DialogPrimitive.Content>
43
+ </DialogPortal>
44
+ ))
45
+ DialogContent.displayName = DialogPrimitive.Content.displayName
46
+
47
+ const DialogHeader = ({
48
+ className,
49
+ ...props
50
+ }) => (
51
+ <div
52
+ className={cn("flex flex-col space-y-1.5 text-center sm:text-left", className)}
53
+ {...props} />
54
+ )
55
+ DialogHeader.displayName = "DialogHeader"
56
+
57
+ const DialogFooter = ({
58
+ className,
59
+ ...props
60
+ }) => (
61
+ <div
62
+ className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
63
+ {...props} />
64
+ )
65
+ DialogFooter.displayName = "DialogFooter"
66
+
67
+ const DialogTitle = React.forwardRef(({ className, ...props }, ref) => (
68
+ <DialogPrimitive.Title
69
+ ref={ref}
70
+ className={cn("text-lg font-semibold leading-none tracking-tight", className)}
71
+ {...props} />
72
+ ))
73
+ DialogTitle.displayName = DialogPrimitive.Title.displayName
74
+
75
+ const DialogDescription = React.forwardRef(({ className, ...props }, ref) => (
76
+ <DialogPrimitive.Description
77
+ ref={ref}
78
+ className={cn("text-sm text-muted-foreground", className)}
79
+ {...props} />
80
+ ))
81
+ DialogDescription.displayName = DialogPrimitive.Description.displayName
82
+
83
+ export {
84
+ Dialog,
85
+ DialogPortal,
86
+ DialogOverlay,
87
+ DialogClose,
88
+ DialogTrigger,
89
+ DialogContent,
90
+ DialogHeader,
91
+ DialogFooter,
92
+ DialogTitle,
93
+ DialogDescription,
94
+ }