lipgloss
lipgloss copied to clipboard
fix: include borders in width calculation
Fix for https://github.com/charmbracelet/lipgloss/issues/298#issuecomment-2512430754
This PR ensures Style.Width() applies to the total rendered width, including borders and padding. This fixes cases where text with borders overflowed the set width.
- Wrap width now subtracts both padding and border size.
- Horizontal alignment uses the inner width (excluding borders).
- Added tests to verify rendered output never exceeds the configured width.
Example program to see the issue live:
package main
import (
"fmt"
"github.com/charmbracelet/bubbles/list"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
type item struct {
title string
desc string
}
func (i item) Title() string { return i.title }
func (i item) Description() string { return i.desc }
func (i item) FilterValue() string { return i.title }
type model struct {
list list.Model
width int
containerStyle lipgloss.Style
}
func newModel() model {
items := make([]list.Item, 0, 10)
for n := 1; n <= 10; n++ {
items = append(items, item{
title: fmt.Sprintf("Item %d", n),
desc: "Placeholder description",
})
}
delegate := list.NewDefaultDelegate()
l := list.New(items, delegate, 0, 0)
l.Title = "Test"
m := model{list: l}
m.containerStyle = lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
Padding(0, 1)
return m
}
func (m model) Init() tea.Cmd { return nil }
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg := msg.(type) {
case tea.WindowSizeMsg:
m.width = msg.Width
wFrame, hFrame := m.containerStyle.GetFrameSize()
wList := msg.Width - wFrame
hList := msg.Height - hFrame
m.list.SetSize(wList, hList)
return m, nil
default:
var cmd tea.Cmd
m.list, cmd = m.list.Update(msg)
return m, cmd
}
}
func (m model) View() string {
c := m.containerStyle
s := c.Width(m.width)
return s.Render(m.list.View())
}
func main() {
p := tea.NewProgram(newModel(), tea.WithAltScreen())
if _, err := p.Run(); err != nil {
fmt.Println("Error:", err)
}
}
Just a heads up that we haven't forgotten about this one, @samox73.
It might also be worth checking to see if this is still valid in the v2-exp branch as we're more or less approaching a v2-release and all our new efforts are going there.