Compare commits

...

2 Commits

Author SHA1 Message Date
waleed
f83d9ee5a2 ack comments 2026-02-05 18:01:33 -08:00
waleed
1cfa12538e fix(cmdk): clean up search modal input handling 2026-02-05 14:32:09 -08:00

View File

@@ -79,7 +79,9 @@ export function SearchModal({
const router = useRouter() const router = useRouter()
const workspaceId = params.workspaceId as string const workspaceId = params.workspaceId as string
const inputRef = useRef<HTMLInputElement>(null) const inputRef = useRef<HTMLInputElement>(null)
const listRef = useRef<HTMLDivElement>(null)
const [mounted, setMounted] = useState(false) const [mounted, setMounted] = useState(false)
const [search, setSearch] = useState('')
const openSettingsModal = useSettingsModalStore((state) => state.openModal) const openSettingsModal = useSettingsModalStore((state) => state.openModal)
const { config: permissionConfig } = usePermissionConfig() const { config: permissionConfig } = usePermissionConfig()
@@ -142,42 +144,19 @@ export function SearchModal({
) )
useEffect(() => { useEffect(() => {
if (open && inputRef.current) { if (open) {
const nativeInputValueSetter = Object.getOwnPropertyDescriptor( setSearch('')
window.HTMLInputElement.prototype, inputRef.current?.focus()
'value'
)?.set
if (nativeInputValueSetter) {
nativeInputValueSetter.call(inputRef.current, '')
inputRef.current.dispatchEvent(new Event('input', { bubbles: true }))
}
inputRef.current.focus()
} }
}, [open]) }, [open])
const handleSearchChange = useCallback(() => { const handleSearchChange = useCallback((value: string) => {
requestAnimationFrame(() => { setSearch(value)
const list = document.querySelector('[cmdk-list]') if (listRef.current) {
if (list) { listRef.current.scrollTop = 0
list.scrollTop = 0
} }
})
}, []) }, [])
useEffect(() => {
if (!open) return
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
e.preventDefault()
onOpenChange(false)
}
}
document.addEventListener('keydown', handleKeyDown)
return () => document.removeEventListener('keydown', handleKeyDown)
}, [open, onOpenChange])
const handleBlockSelect = useCallback( const handleBlockSelect = useCallback(
(block: SearchBlockItem, type: 'block' | 'trigger' | 'tool') => { (block: SearchBlockItem, type: 'block' | 'trigger' | 'tool') => {
const enableTriggerMode = const enableTriggerMode =
@@ -264,7 +243,7 @@ export function SearchModal({
{/* Overlay */} {/* Overlay */}
<div <div
className={cn( className={cn(
'fixed inset-0 z-40 bg-[#E4E4E4]/50 backdrop-blur-[0.75px] transition-opacity duration-100 dark:bg-[#0D0D0D]/50', 'fixed inset-0 z-40 bg-[#E4E4E4]/50 transition-opacity duration-100 dark:bg-[#0D0D0D]/50',
open ? 'opacity-100' : 'pointer-events-none opacity-0' open ? 'opacity-100' : 'pointer-events-none opacity-0'
)} )}
onClick={() => onOpenChange(false)} onClick={() => onOpenChange(false)}
@@ -281,16 +260,31 @@ export function SearchModal({
'-translate-x-1/2 fixed top-[15%] left-1/2 z-50 w-[500px] overflow-hidden rounded-[12px] border border-[var(--border)] bg-[var(--surface-4)] shadow-lg', '-translate-x-1/2 fixed top-[15%] left-1/2 z-50 w-[500px] overflow-hidden rounded-[12px] border border-[var(--border)] bg-[var(--surface-4)] shadow-lg',
open ? 'visible opacity-100' : 'invisible opacity-0' open ? 'visible opacity-100' : 'invisible opacity-0'
)} )}
onKeyDown={(e) => {
if (e.key === 'Escape') {
e.preventDefault()
onOpenChange(false)
}
}}
> >
<Command label='Search' filter={customFilter}> <Command label='Search' filter={customFilter}>
<Command.Input <Command.Input
ref={inputRef} ref={inputRef}
autoFocus value={search}
onValueChange={handleSearchChange} onValueChange={handleSearchChange}
onKeyDown={(e) => {
if (e.key === 'Escape') {
e.preventDefault()
onOpenChange(false)
}
}}
placeholder='Search anything...' placeholder='Search anything...'
className='w-full border-0 border-[var(--border)] border-b bg-transparent px-[12px] py-[10px] font-base text-[15px] text-[var(--text-primary)] placeholder:text-[var(--text-secondary)] focus:outline-none' className='w-full border-0 border-[var(--border)] border-b bg-transparent px-[12px] py-[10px] font-base text-[15px] text-[var(--text-primary)] placeholder:text-[var(--text-secondary)] focus:outline-none'
/> />
<Command.List className='scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent max-h-[400px] overflow-y-auto p-[8px]'> <Command.List
ref={listRef}
className='scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent max-h-[400px] overflow-y-auto p-[8px]'
>
<Command.Empty className='flex items-center justify-center px-[16px] py-[24px] text-[15px] text-[var(--text-subtle)]'> <Command.Empty className='flex items-center justify-center px-[16px] py-[24px] text-[15px] text-[var(--text-subtle)]'>
No results found. No results found.
</Command.Empty> </Command.Empty>