charmbracelet / charmbracelet/bubbles

Viewport's maxYOffset() should consider top / bottom borders

Open
#336 2 comments 2 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
8.9k
Forks
457
Avg merge
1d 18h
Merged PRs (30d)
5

Description

When a border style is applied to a viewport, the last line (or two lines) of the viewport's rendered content will be hidden when scrolling or calling `SetYOffset()`. This is because setting YOffset is clamped to `maxYOffset()`, which doesn't account for the fact that a border subtracts from its content-renderable height.

_Ex. Identical content rendered in un-bordered & bordered viewports after scrolling all the way down
(note that line 9 and line 10 cannot be reached):_
![truncation_example](https://user-images.githubusercontent.com/3377325/221052047-fb066950-5131-45b3-967c-c2b3eb7e2012.png)

_Example code_
```go
package main

import (
"fmt"
"os"

"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)

const (
viewH = 5
viewW = 10
content = "line 1\nline 2\nline 3\nline 4\nline 5\nline 6\nline 7\nline 8\nline 9\nline 10"
)

var (
borderStyle = lipgloss.NewStyle().Border(lipgloss.RoundedBorder())
noBorderStyle = lipgloss.NewStyle()
)

type model struct {
view1 viewport.Model
view2 viewport.Model
}

func (m *model) Init() tea.Cmd {
return nil
}

func (m *model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.view1, _ = m.view1.Update(msg)
m.view2, _ = m.view2.Update(msg)
return m, nil
}

func (m *model) View() string {
view1Content := m.view1.View()
view2Content := m.view2.View()
combined := lipgloss.JoinHorizontal(lipgloss.Left, view1Content, view2Content)
return combined
}

func main() {
view1 := viewport.New(viewW, viewH)
view1.Style = noBorderStyle
view1.SetContent(content)

view2 := viewport.New(viewW, viewH)
view2.Style = borderStyle
view2.SetContent(content)

m := &model{
view1: view1,
view2: view2,
}

p := tea.NewProgram(m)
if _, err := p.Run(); err != nil {
fmt.Println("Run error:", err)
os.Exit(1)
}
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.