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