mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-02 19:00:49 +08:00
fix(ui): sync provider quick switch highlight with scroll target
This commit is contained in:
@@ -28,6 +28,8 @@ const PROVIDERS: ProviderNavItem[] = [
|
|||||||
{ id: 'openai', label: 'OpenAI', getIcon: (theme) => (theme === 'dark' ? iconOpenaiDark : iconOpenaiLight) },
|
{ id: 'openai', label: 'OpenAI', getIcon: (theme) => (theme === 'dark' ? iconOpenaiDark : iconOpenaiLight) },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const HEADER_OFFSET = 24;
|
||||||
|
|
||||||
export function ProviderNav() {
|
export function ProviderNav() {
|
||||||
const resolvedTheme = useThemeStore((state) => state.resolvedTheme);
|
const resolvedTheme = useThemeStore((state) => state.resolvedTheme);
|
||||||
const [activeProvider, setActiveProvider] = useState<ProviderId | null>(null);
|
const [activeProvider, setActiveProvider] = useState<ProviderId | null>(null);
|
||||||
@@ -45,37 +47,27 @@ export function ProviderNav() {
|
|||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
const containerRect = container.getBoundingClientRect();
|
const containerRect = container.getBoundingClientRect();
|
||||||
const triggerPoint = containerRect.top + containerRect.height * 0.3;
|
const activationLine = containerRect.top + HEADER_OFFSET + 1;
|
||||||
|
|
||||||
let currentActive: ProviderId | null = null;
|
let currentActive: ProviderId | null = null;
|
||||||
let closestAbove: { id: ProviderId; top: number } | null = null;
|
|
||||||
|
|
||||||
for (const provider of PROVIDERS) {
|
for (const provider of PROVIDERS) {
|
||||||
const element = document.getElementById(`provider-${provider.id}`);
|
const element = document.getElementById(`provider-${provider.id}`);
|
||||||
if (element) {
|
if (!element) continue;
|
||||||
const rect = element.getBoundingClientRect();
|
|
||||||
const elementTop = rect.top;
|
|
||||||
const elementBottom = rect.bottom;
|
|
||||||
|
|
||||||
// Check if triggerPoint is within this element's bounds
|
const rect = element.getBoundingClientRect();
|
||||||
if (triggerPoint >= elementTop && triggerPoint < elementBottom) {
|
if (rect.top <= activationLine) {
|
||||||
currentActive = provider.id;
|
currentActive = provider.id;
|
||||||
break;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// Track the element whose top is closest to (but not exceeding) triggerPoint
|
|
||||||
// This handles short cards where triggerPoint may have passed the bottom
|
|
||||||
if (elementTop <= triggerPoint) {
|
|
||||||
if (!closestAbove || elementTop > closestAbove.top) {
|
|
||||||
closestAbove = { id: provider.id, top: elementTop };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentActive) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no element contains triggerPoint, use the closest one above it
|
if (!currentActive) {
|
||||||
if (!currentActive && closestAbove) {
|
const firstVisible = PROVIDERS.find((provider) =>
|
||||||
currentActive = closestAbove.id;
|
document.getElementById(`provider-${provider.id}`)
|
||||||
|
);
|
||||||
|
currentActive = firstVisible?.id ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
setActiveProvider(currentActive);
|
setActiveProvider(currentActive);
|
||||||
@@ -86,6 +78,7 @@ export function ProviderNav() {
|
|||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
container.addEventListener('scroll', handleScroll, { passive: true });
|
container.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
|
handleScroll();
|
||||||
return () => container.removeEventListener('scroll', handleScroll);
|
return () => container.removeEventListener('scroll', handleScroll);
|
||||||
}, [handleScroll, getScrollContainer]);
|
}, [handleScroll, getScrollContainer]);
|
||||||
|
|
||||||
@@ -96,9 +89,9 @@ export function ProviderNav() {
|
|||||||
|
|
||||||
const containerRect = container.getBoundingClientRect();
|
const containerRect = container.getBoundingClientRect();
|
||||||
const elementRect = element.getBoundingClientRect();
|
const elementRect = element.getBoundingClientRect();
|
||||||
const headerOffset = 24;
|
const scrollTop = container.scrollTop + (elementRect.top - containerRect.top) - HEADER_OFFSET;
|
||||||
const scrollTop = container.scrollTop + (elementRect.top - containerRect.top) - headerOffset;
|
|
||||||
|
|
||||||
|
setActiveProvider(providerId);
|
||||||
container.scrollTo({
|
container.scrollTo({
|
||||||
top: scrollTop,
|
top: scrollTop,
|
||||||
behavior: 'smooth',
|
behavior: 'smooth',
|
||||||
|
|||||||
Reference in New Issue
Block a user