From 8190df8cf2a8d4e2eaf7aba9e9f38c3150cd0684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CBeeRad=E2=80=9D?= Date: Tue, 30 Dec 2025 15:33:12 +1100 Subject: [PATCH] fix: LocalKeyGate popup buttons now clickable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use React Portal to render popup to document.body - Fixes stacking context issue that blocked button clicks - Added mounted state for proper SSR hydration - Increased z-index to 99999 with explicit pointer-events 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/components/auth/LocalKeyGate.tsx | 77 +++++++++++++++------------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/src/components/auth/LocalKeyGate.tsx b/src/components/auth/LocalKeyGate.tsx index 1e3b8a8..202e1a4 100644 --- a/src/components/auth/LocalKeyGate.tsx +++ b/src/components/auth/LocalKeyGate.tsx @@ -1,6 +1,7 @@ "use client"; import { useEffect, useMemo, useState } from 'react'; +import { createPortal } from 'react-dom'; import { isLocalMode } from '@/config/runtime'; import { apiKeyService } from '@/services/storage/apiKeys'; @@ -30,6 +31,11 @@ const buttonStyle: React.CSSProperties = { export function LocalKeyGate({ children }: LocalKeyGateProps) { const isLocal = useMemo(() => isLocalMode(), []); const [hasKeys, setHasKeys] = useState(() => (!isLocal) || apiKeyService.hasUserKeys()); + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + }, []); useEffect(() => { if (!isLocal) return; @@ -47,46 +53,47 @@ export function LocalKeyGate({ children }: LocalKeyGateProps) { } const openApiKeySettings = () => { - if (typeof window !== 'undefined') { - window.dispatchEvent(new CustomEvent('settings:open', { detail: { tab: 'apikeys' } })); - } + window.dispatchEvent(new CustomEvent('settings:open', { detail: { tab: 'apikeys' } })); }; + const popupContent = ( +
+
+
+

Connect your AI keys

+

+ Local mode needs an OpenAI or Anthropic key. Add one under Settings → API Keys + to unlock the workspace. +

+
+
+ + +
+
+
+ ); + return ( <> {children} -
-
-
-

Connect your AI keys

-

- Local mode needs an OpenAI or Anthropic key. Add one under Settings → API Keys - to unlock the workspace. -

-
-
- - -
-
-
+ {mounted && createPortal(popupContent, document.body)} ); }