A command component in neobrutalism style.
1"use client"
2
3import { Command as CommandPrimitive } from "cmdk"
4import { Search } from "lucide-react"
5
6import * as React from "react"
7
8import {
9 Dialog,
10 DialogContent,
11 DialogDescription,
12 DialogHeader,
13 DialogTitle,
14} from "@/components/ui/dialog"
15
16import { cn } from "@/lib/utils"
17
18function Command({
19 className,
20 ...props
21}: React.ComponentProps<typeof CommandPrimitive>) {
22 return (
23 <CommandPrimitive
24 data-slot="command"
25 className={cn(
26 "flex h-full w-full flex-col overflow-hidden rounded-[0px] border-2 border-border bg-main font-base text-main-foreground",
27 className,
28 )}
29 {...props}
30 />
31 )
32}
33
34function CommandDialog({
35 title = "Command Palette",
36 description = "Search for a command to run...",
37 children,
38 ...props
39}: React.ComponentProps<typeof Dialog> & {
40 title?: string
41 description?: string
42}) {
43 return (
44 <Dialog {...props}>
45 <DialogHeader className="sr-only">
46 <DialogTitle>{title}</DialogTitle>
47 <DialogDescription>{description}</DialogDescription>
48 </DialogHeader>
49 <DialogContent className="overflow-hidden p-0 rounded-[0px]! shadow-shadow border-0">
50 <Command className="**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-heading [&_[cmdk-group-heading]]:mb-1 [&_[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">
51 {children}
52 </Command>
53 </DialogContent>
54 </Dialog>
55 )
56}
57
58function CommandInput({
59 className,
60 ...props
61}: React.ComponentProps<typeof CommandPrimitive.Input>) {
62 return (
63 <div
64 data-slot="command-input-wrapper"
65 className="flex h-9 gap-2 items-center border-b-2 border-border px-3"
66 >
67 <Search className="size-4 shrink-0" />
68 <CommandPrimitive.Input
69 data-slot="command-input"
70 className={cn(
71 "flex h-10 w-full rounded-base bg-transparent py-3 text-sm outline-hidden placeholder:text-main-foreground placeholder:opacity-50 disabled:cursor-not-allowed disabled:opacity-50",
72 className,
73 )}
74 {...props}
75 />
76 </div>
77 )
78}
79
80function CommandList({
81 className,
82 ...props
83}: React.ComponentProps<typeof CommandPrimitive.List>) {
84 return (
85 <CommandPrimitive.List
86 data-slot="command-list"
87 className={cn(
88 "max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
89 className,
90 )}
91 {...props}
92 />
93 )
94}
95
96function CommandEmpty({
97 className,
98 ...props
99}: React.ComponentProps<typeof CommandPrimitive.Empty>) {
100 return (
101 <CommandPrimitive.Empty
102 data-slot="command-empty"
103 className={cn("py-6 text-center text-sm", className)}
104 {...props}
105 />
106 )
107}
108
109function CommandGroup({
110 className,
111 ...props
112}: React.ComponentProps<typeof CommandPrimitive.Group>) {
113 return (
114 <CommandPrimitive.Group
115 data-slot="command-group"
116 className={cn(
117 "text-main-foreground overflow-hidden p-2 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-base [&_[cmdk-group-heading]]:font-heading",
118 className,
119 )}
120 {...props}
121 />
122 )
123}
124
125function CommandSeparator({
126 className,
127 ...props
128}: React.ComponentProps<typeof CommandPrimitive.Separator>) {
129 return (
130 <CommandPrimitive.Separator
131 data-slot="command-separator"
132 className={cn("-mx-1 h-0.5 bg-border", className)}
133 {...props}
134 />
135 )
136}
137
138function CommandItem({
139 className,
140 ...props
141}: React.ComponentProps<typeof CommandPrimitive.Item>) {
142 return (
143 <CommandPrimitive.Item
144 data-slot="command-item"
145 className={cn(
146 "relative flex cursor-default select-none items-center rounded-base px-2 py-1.5 gap-2 text-sm text-main-foreground outline-border outline-0 aria-selected:outline-2 data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
147 className,
148 )}
149 {...props}
150 />
151 )
152}
153
154function CommandShortcut({
155 className,
156 ...props
157}: React.ComponentProps<"span">) {
158 return (
159 <span
160 data-slot="command-shortcut"
161 className={cn(
162 "ml-auto text-xs tracking-widest text-main-foreground",
163 className,
164 )}
165 {...props}
166 />
167 )
168}
169
170export {
171 Command,
172 CommandDialog,
173 CommandInput,
174 CommandList,
175 CommandEmpty,
176 CommandGroup,
177 CommandItem,
178 CommandShortcut,
179 CommandSeparator,
180}
181