Skip to main content
Glama
northernvariables

FedMCP - Federal Parliamentary Information

Tabs.tsx2.65 kB
/** * Simple tabs component */ 'use client'; import { ReactNode, useState, useEffect, useRef, useMemo } from 'react'; export interface Tab { id: string; label: string; content: ReactNode; } interface TabsProps { tabs: Tab[]; defaultTab?: string; onTabChange?: (tabId: string) => void; } export function Tabs({ tabs, defaultTab, onTabChange }: TabsProps) { const [activeTab, setActiveTab] = useState(defaultTab || tabs[0]?.id); const onTabChangeRef = useRef(onTabChange); // Memoize tab IDs to avoid re-running effect when tabs array is recreated with same IDs const tabIdsKey = useMemo(() => tabs.map(t => t.id).join(','), [tabs]); // Keep ref up to date useEffect(() => { onTabChangeRef.current = onTabChange; }, [onTabChange]); // Handle URL hash on mount and hash changes useEffect(() => { const handleHashChange = () => { const hash = window.location.hash.slice(1); // Remove the '#' if (hash && tabs.some(tab => tab.id === hash)) { setActiveTab(hash); onTabChangeRef.current?.(hash); } }; // Check hash on mount handleHashChange(); // Listen for hash changes window.addEventListener('hashchange', handleHashChange); return () => window.removeEventListener('hashchange', handleHashChange); }, [tabIdsKey, tabs]); // Only re-run if tab IDs change const activeTabContent = tabs.find((tab) => tab.id === activeTab)?.content; const handleTabClick = (tabId: string) => { setActiveTab(tabId); // Update URL hash without triggering a page reload window.history.pushState(null, '', `#${tabId}`); // Call the onTabChange callback if provided onTabChangeRef.current?.(tabId); }; return ( <div className="space-y-6"> {/* Tab buttons */} <div className="border-b border-border-subtle"> <div className="flex space-x-8"> {tabs.map((tab) => ( <button key={tab.id} onClick={() => handleTabClick(tab.id)} data-tab-id={tab.id} className={`pb-4 px-1 text-sm font-medium transition-colors relative ${ activeTab === tab.id ? 'text-accent-red' : 'text-text-secondary hover:text-text-primary' }`} > {tab.label} {activeTab === tab.id && ( <div className="absolute bottom-0 left-0 right-0 h-0.5 bg-accent-red" /> )} </button> ))} </div> </div> {/* Tab content */} <div className="animate-fade-in">{activeTabContent}</div> </div> ); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/northernvariables/FedMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server