Skip to content

Commit a5f7397

Browse files
committed
Fix snapshot editor tab bar redraw
1 parent 6b33bdb commit a5f7397

2 files changed

Lines changed: 106 additions & 17 deletions

File tree

internal/ui/snapshot_editor.go

Lines changed: 94 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
446539
func (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()

internal/ui/snapshot_editor_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
tea "github.com/charmbracelet/bubbletea"
10+
"github.com/charmbracelet/lipgloss"
1011
"github.com/stretchr/testify/assert"
1112
"github.com/stretchr/testify/require"
1213

@@ -232,6 +233,17 @@ func TestSnapshotEditorTabSwitch(t *testing.T) {
232233
assert.Equal(t, 0, updated.activeTab)
233234
}
234235

236+
func TestSnapshotEditorRenderTabBarFitsWidth(t *testing.T) {
237+
m := NewSnapshotEditor(makeTestSnapshot())
238+
m.width = 60
239+
m.activeTab = 4
240+
241+
rendered := m.renderTabBar()
242+
assert.LessOrEqual(t, lipgloss.Width(rendered), m.width)
243+
assert.Contains(t, rendered, "5/5")
244+
assert.Contains(t, rendered, "macOS Prefs")
245+
}
246+
235247
func TestSnapshotEditorSpaceTogglesItem(t *testing.T) {
236248
m := NewSnapshotEditor(makeTestSnapshot())
237249
assert.True(t, m.tabs[0].items[0].selected)

0 commit comments

Comments
 (0)