From d4aacf1bea4531a2e1267477bb002bbce537a843 Mon Sep 17 00:00:00 2001 From: lucaronin Date: Mon, 13 Apr 2026 13:42:46 +0200 Subject: [PATCH] fix: focus command palette ai mode immediately --- src/components/CommandPalette.test.tsx | 10 ++++++++++ src/components/CommandPalette.tsx | 22 ++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/components/CommandPalette.test.tsx b/src/components/CommandPalette.test.tsx index 263686be..f99a4ae0 100644 --- a/src/components/CommandPalette.test.tsx +++ b/src/components/CommandPalette.test.tsx @@ -235,6 +235,16 @@ describe('CommandPalette', () => { expect(screen.queryByText('Search Notes')).not.toBeInTheDocument() }) + it('focuses the AI editor immediately when the leading space triggers AI mode', () => { + render() + + const input = screen.getByPlaceholderText('Type a command...') + input.focus() + fireEvent.change(input, { target: { value: ' ' } }) + + expect(screen.getByTestId('command-palette-ai-input')).toHaveFocus() + }) + it('returns to command mode when the leading space is deleted', () => { render( , diff --git a/src/components/CommandPalette.tsx b/src/components/CommandPalette.tsx index 58702f0f..ae0d2d8a 100644 --- a/src/components/CommandPalette.tsx +++ b/src/components/CommandPalette.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useRef, useState } from 'react' +import { useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react' import { cn } from '@/lib/utils' import type { VaultEntry } from '../types' import { fuzzyMatch } from '../utils/fuzzyMatch' @@ -205,15 +205,17 @@ function OpenCommandPalette({ const aiMode = aiValue.startsWith(' ') const { groups, flatList } = usePaletteResults(commands, query) - useEffect(() => { - const focusTimer = window.setTimeout(() => { - if (aiMode) { - aiInputRef.current?.focus() - return - } - inputRef.current?.focus() - }, 50) - return () => window.clearTimeout(focusTimer) + useLayoutEffect(() => { + const target = aiMode ? aiInputRef.current : inputRef.current + if (!target) return + + target.focus() + if (document.activeElement === target) return + + const focusRetry = window.requestAnimationFrame(() => { + target.focus() + }) + return () => window.cancelAnimationFrame(focusRetry) }, [aiMode]) useEffect(() => {