All files / shared / components CommandSearch.tsx

46.55% Statements 27/58
19.23% Branches 5/26
42.1% Functions 8/19
50.98% Lines 26/51

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73        49x   49x 49x 1x                                                     266x 266x 266x 266x                   96x 96x   266x       266x                                  
import { useEffect, useState, useCallback } from 'react'
import { useNavigate } from 'react-router-dom'
import { Command } from 'cmdk'
import {
  Dialog,
  DialogContent,
} from '@/components/ui/dialog'
 
const actions = [
  { id: 'dashboard', label: 'Go to Dashboard', route: '/' },
  { id: 'projects', label: 'Go to Projects', route: '/projects' },
  { id: 'new-project', label: 'New Project', route: '/projects/new' },
  { id: 'runs', label: 'Go to Runs', route: '/runs' },
  { id: 'settings', label: 'Go to Settings', route: '/settings' },
]
 
export function CommandSearch() {
  const [open, setOpen] = useState(false)
  const navigate = useNavigate()
 
  useEffect(() => {
    function handler(e: KeyboardEvent) {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
        e.preventDefault()
        setOpen(true)
      }
      if (e.key === 'Escape') {
        setOpen(false)
      }
    }
    document.addEventListener('keydown', handler)
    return () => document.removeEventListener('keydown', handler)
  }, [])
 
  const handleSelect = useCallback(
    (route: string) => {
      setOpen(false)
      navigate(route)
    },
    [navigate],
  )

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogContent className="top-[15%] max-w-lg">
        <Command className="rounded-lg border shadow-md">
          <Command.Input
            placeholder="Search pages..."
            className="w-full border-none px-4 py-3 text-sm outline-none"
          />
          <Command.List className="max-h-64 overflow-y-auto p-2">
            <Command.Empty className="py-6 text-center text-sm text-muted-foreground">
              No results found
            </Command.Empty>
            <Command.Group heading="Navigation">
              {actions.map((a) => (
                <Command.Item
                  key={a.id}
                  value={a.label}
                  onSelect={() => handleSelect(a.route)}
                  className="flex cursor-pointer items-center rounded-md px-3 py-2 text-sm hover:bg-accent aria-selected:bg-accent"
                >
                  {a.label}
                </Command.Item>
              ))}
            </Command.Group>
          </Command.List>
        </Command>
      </DialogContent>
    </Dialog>
  )
}