UNPKG

@mcp-shark/mcp-shark

Version:

Aggregate multiple Model Context Protocol (MCP) servers into a single unified interface with a powerful monitoring UI. Prov deep visibility into every request and response.

141 lines (139 loc) 4.72 kB
import { colors, fonts } from '../../theme'; import { MenuIcon, ChevronDownIcon } from '../TabNavigationIcons'; export default function MobileDropdown({ tabs, activeTab, onTabChange, isDropdownOpen, setIsDropdownOpen, dropdownRef, }) { return ( <div style={{ position: 'relative', flex: 1, display: 'flex', justifyContent: 'flex-end' }} ref={dropdownRef} > <button onClick={() => setIsDropdownOpen(!isDropdownOpen)} style={{ display: 'flex', alignItems: 'center', gap: '8px', padding: '10px 16px', background: isDropdownOpen ? colors.bgSecondary : 'transparent', border: 'none', borderRadius: '8px', color: colors.textPrimary, cursor: 'pointer', fontSize: '14px', fontFamily: fonts.body, fontWeight: '500', }} onMouseEnter={(e) => { if (!isDropdownOpen) { e.currentTarget.style.background = colors.bgHover; } }} onMouseLeave={(e) => { if (!isDropdownOpen) { e.currentTarget.style.background = 'transparent'; } }} > <MenuIcon size={18} color={colors.textPrimary} /> <span>{tabs.find((t) => t.id === activeTab)?.label || 'Menu'}</span> <div style={{ transform: isDropdownOpen ? 'rotate(180deg)' : 'rotate(0deg)', transition: 'transform 0.2s', display: 'flex', alignItems: 'center', }} > <ChevronDownIcon size={14} color={colors.textPrimary} /> </div> </button> {isDropdownOpen && ( <div style={{ position: 'absolute', top: '100%', right: 0, marginTop: '8px', background: colors.bgCard, border: `1px solid ${colors.borderLight}`, borderRadius: '8px', boxShadow: `0 4px 12px ${colors.shadowSm}`, minWidth: '280px', zIndex: 1000, overflow: 'hidden', }} > {tabs.map((tab) => { const Icon = tab.icon; return ( <button key={tab.id} onClick={() => { onTabChange(tab.id); setIsDropdownOpen(false); }} style={{ width: '100%', padding: '14px 16px', background: activeTab === tab.id ? colors.bgSecondary : 'transparent', border: 'none', borderLeft: activeTab === tab.id ? `3px solid ${colors.accentBlue}` : '3px solid transparent', color: activeTab === tab.id ? colors.textPrimary : colors.textSecondary, cursor: 'pointer', fontSize: '13px', fontFamily: fonts.body, fontWeight: activeTab === tab.id ? '600' : '400', display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: '4px', textAlign: 'left', transition: 'all 0.2s', }} onMouseEnter={(e) => { if (activeTab !== tab.id) { e.currentTarget.style.background = colors.bgHover; e.currentTarget.style.color = colors.textPrimary; } }} onMouseLeave={(e) => { if (activeTab !== tab.id) { e.currentTarget.style.background = 'transparent'; e.currentTarget.style.color = colors.textSecondary; } }} > <div style={{ display: 'flex', alignItems: 'center', gap: '10px', width: '100%' }}> <div style={{ display: 'flex', alignItems: 'center', color: 'currentColor' }}> <Icon size={16} /> </div> <span style={{ flex: 1 }}>{tab.label}</span> </div> <div style={{ fontSize: '11px', color: activeTab === tab.id ? colors.textSecondary : colors.textTertiary, fontWeight: '400', fontFamily: fonts.body, marginLeft: '26px', }} > {tab.description} </div> </button> ); })} </div> )} </div> ); }