import React from 'react'; import { Box, Text } from 'ink'; import { colors } from '../theme/index.js'; export interface Tab { /** Unique identifier for the tab */ id: string; /** Display label for the tab */ label: string; } export interface TabsProps { /** Array of tabs to display */ tabs: Tab[]; /** ID of the currently active tab */ activeTab: string; /** Callback when active tab changes */ onChange: (tabId: string) => void; } /** * Horizontal tab navigation component * * Displays a row of tabs with visual indication of the active tab. * Keyboard navigation is handled by the parent component. * * @example * const tabs = [ * { id: 'files', label: 'Files' }, * { id: 'peers', label: 'Peers' }, * ]; * * * // Output: * // [Files] Peers Trackers Log */ export const Tabs: React.FC = ({ tabs, activeTab }) => { return ( {tabs.map((tab, index) => { const isActive = tab.id === activeTab; const tabNumber = index + 1; return ( {isActive ? ( [ {tabNumber}:{tab.label} ] ) : ( {tabNumber}:{tab.label} )} ); })} ); }; /** * Get the next tab ID in a circular manner * * @param tabs - Array of tabs * @param currentTab - Current active tab ID * @param direction - 1 for next, -1 for previous * @returns The next/previous tab ID */ export function getAdjacentTab( tabs: Tab[], currentTab: string, direction: 1 | -1 ): string { const currentIndex = tabs.findIndex((t) => t.id === currentTab); if (currentIndex === -1) return tabs[0]?.id ?? ''; const newIndex = (currentIndex + direction + tabs.length) % tabs.length; return tabs[newIndex].id; } /** * Get tab ID by number (1-based index) * * @param tabs - Array of tabs * @param num - 1-based tab number * @returns The tab ID or undefined if out of range */ export function getTabByNumber(tabs: Tab[], num: number): string | undefined { const index = num - 1; if (index >= 0 && index < tabs.length) { return tabs[index].id; } return undefined; } export default Tabs;