diff --git a/src/App.tsx b/src/App.tsx index 1ac823033..227deae61 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -42,7 +42,6 @@ import { openclawKeys, useOpenClawHealth } from "@/hooks/useOpenClaw"; import { hermesKeys, useOpenHermesWebUI } from "@/hooks/useHermes"; import { hermesApi } from "@/lib/api/hermes"; import { useProxyStatus } from "@/hooks/useProxyStatus"; -import { useAutoCompact } from "@/hooks/useAutoCompact"; import { useUsageCacheBridge } from "@/hooks/useUsageCacheBridge"; import { useTauriEvent } from "@/hooks/useTauriEvent"; import { useLastValidValue } from "@/hooks/useLastValidValue"; @@ -247,9 +246,6 @@ function App() { const effectiveEditingProvider = useLastValidValue(editingProvider); const effectiveUsageProvider = useLastValidValue(usageProvider); - const toolbarRef = useRef(null); - const isToolbarCompact = useAutoCompact(toolbarRef); - useUsageCacheBridge(); const promptPanelRef = useRef(null); @@ -1277,10 +1273,7 @@ function App() { )} -
+
diff --git a/src/components/AppSwitcher.tsx b/src/components/AppSwitcher.tsx index 06bc5368b..bff3a2054 100644 --- a/src/components/AppSwitcher.tsx +++ b/src/components/AppSwitcher.tsx @@ -15,7 +15,6 @@ interface AppSwitcherProps { activeApp: AppId; onSwitch: (app: AppId) => void; visibleApps?: VisibleApps; - compact?: boolean; } const ALL_APPS: AppId[] = [ @@ -34,7 +33,6 @@ export function AppSwitcher({ activeApp, onSwitch, visibleApps, - compact, }: AppSwitcherProps) { const handleSwitch = (app: AppId) => { if (app === activeApp) return; @@ -80,6 +78,8 @@ export function AppSwitcher({ key={app} type="button" onClick={() => handleSwitch(app)} + title={appDisplayName[app]} + aria-label={appDisplayName[app]} className={cn( "group inline-flex items-center px-3 h-8 rounded-md text-sm font-medium transition-all duration-200", isActive @@ -115,16 +115,6 @@ export function AppSwitcher({ )} - - {appDisplayName[app]} - ); })} diff --git a/src/hooks/useAutoCompact.ts b/src/hooks/useAutoCompact.ts deleted file mode 100644 index b5b7bca39..000000000 --- a/src/hooks/useAutoCompact.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { useEffect, useRef, useState, type RefObject } from "react"; - -/** - * Detects whether the container's children overflow the available width - * and returns a `compact` flag for the AppSwitcher. - * - * Uses ResizeObserver on a flex-constrained container. The container - * must have `flex-1 min-w-0 overflow-hidden` so its width is determined - * by the parent layout, not its own content — avoiding the oscillation - * problem when toggling compact mode. - */ -export function useAutoCompact( - containerRef: RefObject, -): boolean { - const [compact, setCompact] = useState(false); - const normalWidthRef = useRef(0); - const lockUntilRef = useRef(0); - - useEffect(() => { - const el = containerRef.current; - if (!el) return; - - const ro = new ResizeObserver(() => { - // During expand animation, ignore resize events to prevent flicker - if (Date.now() < lockUntilRef.current) return; - - if (!compact) { - // Overflow detected → switch to compact - if (el.scrollWidth > el.clientWidth + 1) { - // Cache only at the overflow edge: when content fits, - // scrollWidth === clientWidth (DOM spec), so caching unconditionally - // would pollute normalWidthRef with the container width (e.g. after - // maximizing), making the expand threshold unreachable. - normalWidthRef.current = el.scrollWidth; - setCompact(true); - } - } else if (normalWidthRef.current > 0) { - // In compact mode: only recover to normal if - // available space >= what normal mode needed - if (el.clientWidth >= normalWidthRef.current) { - // Lock out resize events during the expand animation (200ms + 50ms margin) - lockUntilRef.current = Date.now() + 250; - setCompact(false); - } - } - }); - ro.observe(el); - return () => ro.disconnect(); - }, [compact]); - - return compact; -}