@@ -443,6 +443,99 @@ func (m SnapshotEditorModel) getVisibleItems() int {
443443 return available
444444}
445445
446+ func (m SnapshotEditorModel ) renderTabBar () string {
447+ totalTabs := len (m .tabs )
448+
449+ arrowStyle := lipgloss .NewStyle ().Foreground (lipgloss .Color ("#555" ))
450+ neighborStyle := lipgloss .NewStyle ().Foreground (lipgloss .Color ("#666" ))
451+ sepStyle := lipgloss .NewStyle ().Foreground (lipgloss .Color ("#444" ))
452+ posStyle := lipgloss .NewStyle ().Foreground (lipgloss .Color ("#555" ))
453+
454+ activeTab := m .tabs [m .activeTab ]
455+ activeCount := 0
456+ for _ , item := range activeTab .items {
457+ if item .selected {
458+ activeCount ++
459+ }
460+ }
461+ activeRendered := activeTabStyle .Render (fmt .Sprintf ("%s (%d)" , activeTab .name , activeCount ))
462+ posRendered := posStyle .Render (fmt .Sprintf (" %d/%d" , m .activeTab + 1 , totalTabs ))
463+
464+ hasLeft := m .activeTab > 0
465+ hasRight := m .activeTab < totalTabs - 1
466+ leftArrow := " "
467+ if hasLeft {
468+ leftArrow = arrowStyle .Render ("‹ " )
469+ }
470+ rightArrow := " "
471+ if hasRight {
472+ rightArrow = arrowStyle .Render (" ›" )
473+ }
474+
475+ termWidth := m .width
476+ if termWidth == 0 {
477+ termWidth = 80
478+ }
479+
480+ baseWidth := lipgloss .Width (leftArrow ) + lipgloss .Width (activeRendered ) + lipgloss .Width (rightArrow ) + lipgloss .Width (posRendered )
481+ remaining := termWidth - baseWidth
482+
483+ sep := sepStyle .Render (" │ " )
484+ sepW := lipgloss .Width (sep )
485+
486+ var leftNeighbors []string
487+ var rightNeighbors []string
488+ li := m .activeTab - 1
489+ ri := m .activeTab + 1
490+
491+ for remaining > 0 && (li >= 0 || ri < totalTabs ) {
492+ added := false
493+ if li >= 0 {
494+ rendered := neighborStyle .Render (m .tabs [li ].name )
495+ w := lipgloss .Width (rendered ) + sepW
496+ if w <= remaining {
497+ leftNeighbors = append ([]string {rendered }, leftNeighbors ... )
498+ remaining -= w
499+ li --
500+ added = true
501+ } else {
502+ li = - 1
503+ }
504+ }
505+ if ri < totalTabs {
506+ rendered := neighborStyle .Render (m .tabs [ri ].name )
507+ w := lipgloss .Width (rendered ) + sepW
508+ if w <= remaining {
509+ rightNeighbors = append (rightNeighbors , rendered )
510+ remaining -= w
511+ ri ++
512+ added = true
513+ } else {
514+ ri = totalTabs
515+ }
516+ }
517+ if ! added {
518+ break
519+ }
520+ }
521+
522+ var result strings.Builder
523+ result .WriteString (leftArrow )
524+ for _ , n := range leftNeighbors {
525+ result .WriteString (n )
526+ result .WriteString (sep )
527+ }
528+ result .WriteString (activeRendered )
529+ for _ , n := range rightNeighbors {
530+ result .WriteString (sep )
531+ result .WriteString (n )
532+ }
533+ result .WriteString (rightArrow )
534+ result .WriteString (posRendered )
535+
536+ return result .String ()
537+ }
538+
446539func (m SnapshotEditorModel ) View () string { //nolint:gocyclo // renders editor sections with per-section formatting; inherent to bubbletea View
447540 if m .searchMode {
448541 return m .viewSearch ()
@@ -465,23 +558,7 @@ func (m SnapshotEditorModel) View() string { //nolint:gocyclo // renders editor
465558 lines = append (lines , "" )
466559 lines = append (lines , activeTabStyle .Render ("📋 Snapshot Editor — Review your captured environment" ))
467560 lines = append (lines , "" )
468-
469- var tabs []string
470- for i , tab := range m .tabs {
471- count := 0
472- for _ , item := range tab .items {
473- if item .selected {
474- count ++
475- }
476- }
477- label := fmt .Sprintf ("%s %s (%d)" , tab .icon , tab .name , count )
478- if i == m .activeTab {
479- tabs = append (tabs , activeTabStyle .Render (label ))
480- } else {
481- tabs = append (tabs , tabStyle .Render (label ))
482- }
483- }
484- lines = append (lines , lipgloss .JoinHorizontal (lipgloss .Top , tabs ... ))
561+ lines = append (lines , m .renderTabBar ())
485562
486563 tab := m .tabs [m .activeTab ]
487564 visibleItems := m .getVisibleItems ()
0 commit comments