1 import * as React from "react"
2 import { type DialogProps } from "@radix-ui/react-dialog"
3 import { Command as CommandPrimitive } from "cmdk"
4 import { Search } from "lucide-react"
5
6 import { cn } from "@/lib/utils"
7 import { Dialog, DialogContent } from "@/components/ui/dialog"
8
9 const Command = React.forwardRef<
10 React.ElementRef<typeof CommandPrimitive>,
11 React.ComponentPropsWithoutRef<typeof CommandPrimitive>
12 >(({ className, ...props }, ref) => (
13 <CommandPrimitive
14 ref={ref}
15 className={cn(
16 "flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground",
17 className
18 )}
19 {...props}
20 />
21 ))
22 Command.displayName = CommandPrimitive.displayName
23
24 const CommandDialog = ({ children, ...props }: DialogProps) => {
25 return (
26 <Dialog {...props}>
27 <DialogContent className="overflow-hidden p-0 shadow-lg">
28 <Command 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">
29 {children}
30 </Command>
31 </DialogContent>
32 </Dialog>
33 )
34 }
35
36 const CommandInput = React.forwardRef<
37 React.ElementRef<typeof CommandPrimitive.Input>,
38 React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
39 >(({ className, ...props }, ref) => (
40 <div className="flex items-center border-b px-3" cmdk-input-wrapper="">
41 <Search className="mr-2 h-4 w-4 shrink-0 opacity-50" />
42 <CommandPrimitive.Input
43 ref={ref}
44 className={cn(
45 "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",
46 className
47 )}
48 {...props}
49 />
50 </div>
51 ))
52
53 CommandInput.displayName = CommandPrimitive.Input.displayName
54
55 const CommandList = React.forwardRef<
56 React.ElementRef<typeof CommandPrimitive.List>,
57 React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
58 >(({ className, ...props }, ref) => (
59 <CommandPrimitive.List
60 ref={ref}
61 className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
62 {...props}
63 />
64 ))
65
66 CommandList.displayName = CommandPrimitive.List.displayName
67
68 const CommandEmpty = React.forwardRef<
69 React.ElementRef<typeof CommandPrimitive.Empty>,
70 React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
71 >((props, ref) => (
72 <CommandPrimitive.Empty
73 ref={ref}
74 className="py-6 text-center text-sm"
75 {...props}
76 />
77 ))
78
79 CommandEmpty.displayName = CommandPrimitive.Empty.displayName
80
81 const CommandGroup = React.forwardRef<
82 React.ElementRef<typeof CommandPrimitive.Group>,
83 React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
84 >(({ className, ...props }, ref) => (
85 <CommandPrimitive.Group
86 ref={ref}
87 className={cn(
88 "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",
89 className
90 )}
91 {...props}
92 />
93 ))
94
95 CommandGroup.displayName = CommandPrimitive.Group.displayName
96
97 const CommandSeparator = React.forwardRef<
98 React.ElementRef<typeof CommandPrimitive.Separator>,
99 React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
100 >(({ className, ...props }, ref) => (
101 <CommandPrimitive.Separator
102 ref={ref}
103 className={cn("-mx-1 h-px bg-border", className)}
104 {...props}
105 />
106 ))
107 CommandSeparator.displayName = CommandPrimitive.Separator.displayName
108
109 const CommandItem = React.forwardRef<
110 React.ElementRef<typeof CommandPrimitive.Item>,
111 React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
112 >(({ className, ...props }, ref) => (
113 <CommandPrimitive.Item
114 ref={ref}
115 className={cn(
116 "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",
117 className
118 )}
119 {...props}
120 />
121 ))
122
123 CommandItem.displayName = CommandPrimitive.Item.displayName
124
125 const CommandShortcut = ({
126 className,
127 ...props
128 }: React.HTMLAttributes<HTMLSpanElement>) => {
129 return (
130 <span
131 className={cn(
132 "ml-auto text-xs tracking-widest text-muted-foreground",
133 className
134 )}
135 {...props}
136 />
137 )
138 }
139 CommandShortcut.displayName = "CommandShortcut"
140
141 export {
142 Command,
143 CommandDialog,
144 CommandInput,
145 CommandList,
146 CommandEmpty,
147 CommandGroup,
148 CommandItem,
149 CommandShortcut,
150 CommandSeparator,
151 }