Files
Will Binns-SmithandGitHub 5099903e88 bundle-analyzer: add kbd shortcut labels and fix focus bugs (#87001)
- Adds decorated kbd-style shortcut labels to cue the user into using them
- Listens only for the appropriate OS or Ctrl key on Mac/Others
- Esc now clears and focuses the search field and the treemap focus
- Does not trigger in the case where the user has another element focused

![image.png](https://app.graphite.com/user-attachments/assets/6a85d1e7-a711-432d-86b0-f65c0b89de74.png)
2025-12-09 23:36:19 -08:00

64 lines
1.6 KiB
TypeScript

'use client'
import { useEffect, useRef, useState } from 'react'
import { Input } from '@/components/ui/input'
import { Kbd } from '@/components/ui/kbd'
interface FileSearchProps {
value: string
onChange: (value: string) => void
}
export function FileSearch({ value, onChange }: FileSearchProps) {
const [focused, setFocused] = useState(false)
const inputRef = useRef<HTMLInputElement>(null)
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
if (
e.key === '/' &&
!['INPUT', 'TEXTAREA'].includes((e.target as HTMLElement).tagName)
) {
e.preventDefault()
inputRef.current?.focus()
} else if (
e.key === 'Escape' &&
document.activeElement === inputRef.current
) {
e.preventDefault()
onChange('')
inputRef.current?.blur()
}
}
window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [onChange])
const handleFocus = () => {
setFocused(true)
}
const handleBlur = () => {
setFocused(false)
}
return (
<div className="relative">
<Input
ref={inputRef}
type="search"
value={value}
onChange={(e) => onChange(e.target.value)}
onFocus={handleFocus}
onBlur={handleBlur}
placeholder="Search files..."
className="w-48 focus:w-80 transition-all duration-200 pr-8"
/>
{!value && !focused && (
<Kbd className="absolute right-2 top-1/2 -translate-y-1/2">/</Kbd>
)}
</div>
)
}