fix: LocalKeyGate popup buttons now clickable
- 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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.5
parent
bcfeb285bb
commit
8190df8cf2
@@ -1,6 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
|
import { createPortal } from 'react-dom';
|
||||||
import { isLocalMode } from '@/config/runtime';
|
import { isLocalMode } from '@/config/runtime';
|
||||||
import { apiKeyService } from '@/services/storage/apiKeys';
|
import { apiKeyService } from '@/services/storage/apiKeys';
|
||||||
|
|
||||||
@@ -30,6 +31,11 @@ const buttonStyle: React.CSSProperties = {
|
|||||||
export function LocalKeyGate({ children }: LocalKeyGateProps) {
|
export function LocalKeyGate({ children }: LocalKeyGateProps) {
|
||||||
const isLocal = useMemo(() => isLocalMode(), []);
|
const isLocal = useMemo(() => isLocalMode(), []);
|
||||||
const [hasKeys, setHasKeys] = useState(() => (!isLocal) || apiKeyService.hasUserKeys());
|
const [hasKeys, setHasKeys] = useState(() => (!isLocal) || apiKeyService.hasUserKeys());
|
||||||
|
const [mounted, setMounted] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMounted(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isLocal) return;
|
if (!isLocal) return;
|
||||||
@@ -47,21 +53,18 @@ export function LocalKeyGate({ children }: LocalKeyGateProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const openApiKeySettings = () => {
|
const openApiKeySettings = () => {
|
||||||
if (typeof window !== 'undefined') {
|
|
||||||
window.dispatchEvent(new CustomEvent('settings:open', { detail: { tab: 'apikeys' } }));
|
window.dispatchEvent(new CustomEvent('settings:open', { detail: { tab: 'apikeys' } }));
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
const popupContent = (
|
||||||
<>
|
|
||||||
{children}
|
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
top: 24,
|
top: 24,
|
||||||
right: 24,
|
right: 24,
|
||||||
maxWidth: 420,
|
maxWidth: 420,
|
||||||
zIndex: 9999
|
zIndex: 99999,
|
||||||
|
pointerEvents: 'auto'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div style={panelStyle}>
|
<div style={panelStyle}>
|
||||||
@@ -73,9 +76,7 @@ export function LocalKeyGate({ children }: LocalKeyGateProps) {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div style={{ display: 'flex', gap: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
|
<div style={{ display: 'flex', gap: 12, justifyContent: 'center', flexWrap: 'wrap' }}>
|
||||||
<button style={buttonStyle} onClick={() => {
|
<button style={buttonStyle} onClick={openApiKeySettings}>
|
||||||
openApiKeySettings();
|
|
||||||
}}>
|
|
||||||
Open API Key Settings
|
Open API Key Settings
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@@ -87,6 +88,12 @@ export function LocalKeyGate({ children }: LocalKeyGateProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{children}
|
||||||
|
{mounted && createPortal(popupContent, document.body)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user