| |
| |
| |
| |
| |
|
|
| import React from 'react'; |
| import { Text, Box } from 'ink'; |
| import { theme } from '../../semantic-colors.js'; |
|
|
| |
| |
| |
| export interface Tab { |
| |
| key: string; |
| |
| header: string; |
| |
| statusIcon?: string; |
| |
| isSpecial?: boolean; |
| } |
|
|
| |
| |
| |
| export interface TabHeaderProps { |
| |
| tabs: Tab[]; |
| |
| currentIndex: number; |
| |
| completedIndices?: Set<number>; |
| |
| showArrows?: boolean; |
| |
| showStatusIcons?: boolean; |
| |
| |
| |
| |
| renderStatusIcon?: ( |
| tab: Tab, |
| index: number, |
| isCompleted: boolean, |
| ) => string | undefined; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| export function TabHeader({ |
| tabs, |
| currentIndex, |
| completedIndices = new Set(), |
| showArrows = true, |
| showStatusIcons = true, |
| renderStatusIcon, |
| }: TabHeaderProps): React.JSX.Element | null { |
| if (tabs.length <= 1) return null; |
|
|
| const getStatusIcon = (tab: Tab, index: number): string => { |
| const isCompleted = completedIndices.has(index); |
|
|
| |
| if (renderStatusIcon) { |
| const customIcon = renderStatusIcon(tab, index, isCompleted); |
| if (customIcon !== undefined) return customIcon; |
| } |
|
|
| |
| if (tab.statusIcon) return tab.statusIcon; |
|
|
| |
| if (tab.isSpecial) return 'β‘'; |
| return isCompleted ? 'β' : 'β‘'; |
| }; |
|
|
| return ( |
| <Box flexDirection="row" marginBottom={1} aria-role="tablist"> |
| {showArrows && <Text color={theme.text.secondary}>{'β '}</Text>} |
| {tabs.map((tab, i) => ( |
| <React.Fragment key={tab.key}> |
| {i > 0 && <Text color={theme.text.secondary}>{' β '}</Text>} |
| {showStatusIcons && ( |
| <Text color={theme.text.secondary}>{getStatusIcon(tab, i)} </Text> |
| )} |
| <Box maxWidth={i !== currentIndex ? 16 : 100}> |
| <Text |
| color={ |
| i === currentIndex ? theme.status.success : theme.text.secondary |
| } |
| bold={i === currentIndex} |
| underline={i === currentIndex} |
| aria-current={i === currentIndex ? 'step' : undefined} |
| wrap="truncate" |
| > |
| {tab.header} |
| </Text> |
| </Box> |
| </React.Fragment> |
| ))} |
| {showArrows && <Text color={theme.text.secondary}>{' β'}</Text>} |
| </Box> |
| ); |
| } |
|
|