You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have been trying to add a debounced search to the CommandMenu for awhile now with no success. I basically want to recreate the search on https://nextjs.org but with articles that a user can search for.
'use client'import{useEffect,useState,useCallback,useRef,ChangeEvent}from'react'import{useRouter}from'next/navigation'import{DialogProps}from'@radix-ui/react-alert-dialog'import{Link2,File,Laptop,Moon,SunMedium}from'lucide-react'import{useTheme}from'next-themes'importdebouncefrom'lodash.debounce'import{cn}from'@lib/utils'import{getSearchResults}from'@lib/sanity.client'import{Button}from'@components/ui/Button'import{CommandDialog,CommandEmpty,CommandGroup,CommandInput,CommandItem,CommandList,CommandSeparator,}from'@components/ui/Command'import{STATIC_NAV_ITEMS}from'@lib/constants'exportfunctionCommandMenu({ ...props}: DialogProps&{divisions: any[]}){constinputRef=useRef<HTMLInputElement>(null)constrouter=useRouter()const[open,setOpen]=useState(false)const[results,setResults]=useState([])const[value,setValue]=useState('')const{ setTheme }=useTheme()const{ divisions }=props// get just the title and slug of categoriesconsttopLevelCategories=divisions.map((division)=>({title: division.name,href: `/news/${division.slug}`,}))letlinks=[...topLevelCategories, ...STATIC_NAV_ITEMS]useEffect(()=>{constdown=(e: KeyboardEvent)=>{if(e.key==='k'&&(e.metaKey||e.ctrlKey)){e.preventDefault()setOpen((open)=>!open)}}document.addEventListener('keydown',down)return()=>document.removeEventListener('keydown',down)},[])construnCommand=useCallback((command: ()=>unknown)=>{setOpen(false)command()},[])constdebouncedSearch=debounce(async()=>{constsearchResults=awaitgetSearchResults({query: value})setResults(searchResults.posts)},500)consthandleSearchChange=useCallback((e)=>{// make sure it's not an empty stringif(e!==''){setValue(e)debouncedSearch()}else{setValue(e)setResults([])}},[debouncedSearch],)return(<><Buttonvariant="outline"className={cn('relative h-9 w-full justify-start rounded-[0.5rem] text-sm text-muted-foreground sm:pr-12 md:w-40 lg:w-64',)}onClick={()=>setOpen(true)}{...props}><spanclassName="hidden lg:inline-flex">Search Redshirt Sports...</span><spanclassName="inline-flex lg:hidden">Search...</span><kbdclassName="pointer-events-none absolute right-1.5 top-2 hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex"><spanclassName="text-xs">⌘</span>K
</kbd></Button><CommandDialogopen={open}onOpenChange={setOpen}><CommandInputref={inputRef}placeholder="Search..."value={value}onValueChange={handleSearchChange}/><CommandList><CommandEmpty>No results found.</CommandEmpty>{results.length>0&&(<CommandGroupheading="Search Results">{results.map((result)=>(<CommandItemkey={result._id}value={result.title}onSelect={()=>{runCommand(()=>router.push(`/${result.slug}`))}}><Link2className="mr-2 h-4 w-4"/>{result.title}</CommandItem>))}</CommandGroup>)}<CommandGroupheading="Links">{links.map((navItem)=>(<CommandItemkey={navItem.href}value={navItem.title}onSelect={()=>{runCommand(()=>router.push(navItem.hrefasstring))}}><Link2className="mr-2 h-4 w-4"/>{navItem.title}</CommandItem>))}<CommandItemvalue="Privacy Policy"onSelect={()=>{runCommand(()=>router.push('/privacy'))}}><Link2className="mr-2 h-4 w-4"/>
Privacy Policy
</CommandItem></CommandGroup><CommandSeparator/>{divisions.map((group)=>group.conferences.length>0&&(<CommandGroupkey={group.name}heading={group.name}>{group.conferences.map((navItem: any)=>(<CommandItemkey={navItem.slug}value={navItem.name}onSelect={()=>{runCommand(()=>router.push(`/news/${group.slug}/${navItem.slug}`))}}><divclassName="mr-2 flex h-4 w-4 items-center justify-center"><FileclassName="h-3 w-3"/></div>{navItem.name}</CommandItem>))}</CommandGroup>),)}<CommandSeparator/><CommandGroupheading="Theme"><CommandItemonSelect={()=>runCommand(()=>setTheme('light'))}><SunMediumclassName="mr-2 h-4 w-4"/>
Light
</CommandItem><CommandItemonSelect={()=>runCommand(()=>setTheme('dark'))}><MoonclassName="mr-2 h-4 w-4"/>
Dark
</CommandItem><CommandItemonSelect={()=>runCommand(()=>setTheme('system'))}><LaptopclassName="mr-2 h-4 w-4"/>
System
</CommandItem></CommandGroup></CommandList></CommandDialog></>)}
When I type something into the search I see that searchResults is populated. I do get some stuff to show up, but it isn't consistent. For example if I search vmi for some reason it's only showing 2 results even though there are 12 results
If I backspace to just vm, I now get 9 results even though my results array has 12 in it.
I feel like I am missing something super obvious. I just want to add actual search functionality to the command menu, not just pass in static items.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I have been trying to add a debounced search to the CommandMenu for awhile now with no success. I basically want to recreate the search on https://nextjs.org but with articles that a user can search for.
When I type something into the search I see that
searchResults
is populated. I do get some stuff to show up, but it isn't consistent. For example if I searchvmi
for some reason it's only showing 2 results even though there are 12 resultsIf I backspace to just
vm
, I now get 9 results even though my results array has 12 in it.I feel like I am missing something super obvious. I just want to add actual search functionality to the command menu, not just pass in static items.
Beta Was this translation helpful? Give feedback.
All reactions