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