From 3ad6c8e4053726f9a76ad83ab446447d1bc2185a Mon Sep 17 00:00:00 2001 From: omercelikdev Date: Mon, 13 Jul 2026 09:15:36 +0300 Subject: [PATCH] fix: no stray focus ring on launch / search click MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The earlier focus-visible change didn't cover the real cause. On every window re-open the OS restores focus to the last-clicked sidebar button, which the browser treats as focus-visible — painting a full orange ring around the History icon on launch. The search field also glowed on click via a focus-within ring. - Sidebar buttons: drop the focus-visible ring. The active tab's accent fill already signals the current view, and restored focus can no longer leave a ring on open. - Search field: remove the focus-within ring for a static, Spotlight-clean box (the caret is the focus cue). - Focus the search input on every window open, so typing filters immediately and focus never sits on a sidebar button to begin with. Co-Authored-By: Claude Opus 4.8 --- src/components/layout/DragBar.tsx | 14 ++++++++++++-- src/components/layout/Sidebar.tsx | 10 ++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/components/layout/DragBar.tsx b/src/components/layout/DragBar.tsx index 88cb3d4..cc1dc96 100644 --- a/src/components/layout/DragBar.tsx +++ b/src/components/layout/DragBar.tsx @@ -8,7 +8,7 @@ const DEBOUNCE_MS = 120; export function SearchBar() { const { t } = useTranslation(); - const { searchQuery, setSearchQuery, activeTab } = useAppStore(); + const { searchQuery, setSearchQuery, activeTab, windowOpenCount } = useAppStore(); const inputRef = useRef(null); const debounceRef = useRef | null>(null); @@ -41,6 +41,16 @@ export function SearchBar() { }; }, []); + // Put the caret in the search box on every window open (settings tab hides + // the bar, so inputRef is simply null there). This lets the user type to + // filter straight away and takes focus off whichever sidebar button the OS + // restored it to — otherwise that restore reads as focus-visible and paints + // a stray ring on launch. + useEffect(() => { + const id = requestAnimationFrame(() => inputRef.current?.focus()); + return () => cancelAnimationFrame(id); + }, [windowOpenCount]); + // Auto-focus search when user starts typing (like Spotlight) useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { @@ -72,7 +82,7 @@ export function SearchBar() { >
inputRef.current?.focus()} > diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx index 9b00a5e..213f8ef 100644 --- a/src/components/layout/Sidebar.tsx +++ b/src/components/layout/Sidebar.tsx @@ -44,9 +44,11 @@ export function Sidebar() { aria-label={label} onClick={() => handleTabChange(id)} className={cn( - // Keyboard users need a visible focus target: suppress the mouse-click - // outline, but keep the focus-visible ring. - 'group relative w-8 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ease-out cursor-pointer no-drag outline-none focus-visible:ring-2 focus-visible:ring-accent', + // No focus ring here: the window restores focus to the last-clicked + // sidebar button on every re-open, which browsers treat as + // focus-visible — a stray orange ring on launch. The active tab's + // accent fill already shows which view is selected. + 'group relative w-8 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ease-out cursor-pointer no-drag outline-none', isActive ? 'bg-accent/15 text-accent' : 'text-foreground/55 hover:text-foreground/80 hover:bg-surface-hover' @@ -84,7 +86,7 @@ export function Sidebar() { aria-pressed={isCapturePaused} onClick={() => toggleCapturePaused()} className={cn( - 'group relative w-8 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ease-out cursor-pointer no-drag outline-none focus-visible:ring-2 focus-visible:ring-accent', + 'group relative w-8 h-8 flex items-center justify-center rounded-lg transition-all duration-100 ease-out cursor-pointer no-drag outline-none', isCapturePaused ? 'bg-amber-500/15 text-amber-500' : 'text-foreground/55 hover:text-foreground/80 hover:bg-surface-hover'