command.jsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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({ className, ...props }) {
  14. return (
  15. <CommandPrimitive
  16. data-slot="command"
  17. className={cn(
  18. "bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md",
  19. className,
  20. )}
  21. {...props}
  22. />
  23. );
  24. }
  25. function CommandDialog({
  26. title = "Befehlsmenü",
  27. description = "Befehl auswählen…",
  28. children,
  29. className,
  30. showCloseButton = true,
  31. ...props
  32. }) {
  33. return (
  34. <Dialog {...props}>
  35. <DialogHeader className="sr-only">
  36. <DialogTitle>{title}</DialogTitle>
  37. <DialogDescription>{description}</DialogDescription>
  38. </DialogHeader>
  39. <DialogContent
  40. className={cn("overflow-hidden p-0", className)}
  41. showCloseButton={showCloseButton}
  42. >
  43. <Command 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">
  44. {children}
  45. </Command>
  46. </DialogContent>
  47. </Dialog>
  48. );
  49. }
  50. function CommandInput({ className, ...props }) {
  51. return (
  52. <div
  53. data-slot="command-input-wrapper"
  54. className="flex h-9 items-center gap-2 border-b px-3"
  55. >
  56. <SearchIcon className="size-4 shrink-0 opacity-50" />
  57. <CommandPrimitive.Input
  58. data-slot="command-input"
  59. className={cn(
  60. "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",
  61. className,
  62. )}
  63. {...props}
  64. />
  65. </div>
  66. );
  67. }
  68. function CommandList({ className, ...props }) {
  69. return (
  70. <CommandPrimitive.List
  71. data-slot="command-list"
  72. className={cn(
  73. "max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
  74. className,
  75. )}
  76. {...props}
  77. />
  78. );
  79. }
  80. function CommandEmpty({ ...props }) {
  81. return (
  82. <CommandPrimitive.Empty
  83. data-slot="command-empty"
  84. className="py-6 text-center text-sm"
  85. {...props}
  86. />
  87. );
  88. }
  89. function CommandGroup({ className, ...props }) {
  90. return (
  91. <CommandPrimitive.Group
  92. data-slot="command-group"
  93. className={cn(
  94. "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",
  95. className,
  96. )}
  97. {...props}
  98. />
  99. );
  100. }
  101. function CommandSeparator({ className, ...props }) {
  102. return (
  103. <CommandPrimitive.Separator
  104. data-slot="command-separator"
  105. className={cn("bg-border -mx-1 h-px", className)}
  106. {...props}
  107. />
  108. );
  109. }
  110. function CommandItem({ className, ...props }) {
  111. return (
  112. <CommandPrimitive.Item
  113. data-slot="command-item"
  114. className={cn(
  115. "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",
  116. className,
  117. )}
  118. {...props}
  119. />
  120. );
  121. }
  122. function CommandShortcut({ className, ...props }) {
  123. return (
  124. <span
  125. data-slot="command-shortcut"
  126. className={cn(
  127. "text-muted-foreground ml-auto text-xs tracking-widest",
  128. className,
  129. )}
  130. {...props}
  131. />
  132. );
  133. }
  134. export {
  135. Command,
  136. CommandDialog,
  137. CommandInput,
  138. CommandList,
  139. CommandEmpty,
  140. CommandGroup,
  141. CommandItem,
  142. CommandShortcut,
  143. CommandSeparator,
  144. };