command.jsx 4.1 KB

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