diff --git a/borders.go b/borders.go index b36f8743..75655cc6 100644 --- a/borders.go +++ b/borders.go @@ -320,8 +320,11 @@ func (s Style) applyBorder(str string) string { width += maxRuneWidth(border.Left) } - if hasRight && border.Right == "" { - border.Right = " " + if hasRight { + if border.Right == "" { + border.Right = " " + } + width += maxRuneWidth(border.Right) } // If corners should be rendered but are set with the empty string, fill them @@ -435,14 +438,19 @@ func renderHorizontalEdge(left, middle, right string, width int) string { out := strings.Builder{} out.WriteString(left) - for i := leftWidth + rightWidth; i < width+rightWidth; { - out.WriteRune(runes[j]) + + // Fill the middle section + middleWidth := width - leftWidth - rightWidth + for i := 0; i < middleWidth; { + r := runes[j] + out.WriteRune(r) + i += ansi.StringWidth(string(r)) j++ if j >= len(runes) { j = 0 } - i += ansi.StringWidth(string(runes[j])) } + out.WriteString(right) return out.String() diff --git a/borders_test.go b/borders_test.go index 44b95d0c..ae5f67a7 100644 --- a/borders_test.go +++ b/borders_test.go @@ -1,6 +1,10 @@ package lipgloss -import "testing" +import ( + "testing" + + "github.com/charmbracelet/x/ansi" +) func TestStyle_GetBorderSizes(t *testing.T) { tests := []struct { @@ -94,3 +98,51 @@ func TestStyle_GetBorderSizes(t *testing.T) { }) } } + +func TestRenderHorizontalEdgeFix(t *testing.T) { + tests := []struct { + name string + left string + middle string + right string + width int + expected int // expected display width + }{ + { + name: "standard border 20 width", + left: "┌", + middle: "─", + right: "┐", + width: 20, + expected: 20, + }, + { + name: "standard border 45 width", + left: "╭", + middle: "─", + right: "╮", + width: 45, + expected: 45, + }, + { + name: "ascii border 30 width", + left: "+", + middle: "-", + right: "+", + width: 30, + expected: 30, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := renderHorizontalEdge(tt.left, tt.middle, tt.right, tt.width) + actual := ansi.StringWidth(result) + + if actual != tt.expected { + t.Errorf("renderHorizontalEdge() width = %d, expected %d", actual, tt.expected) + t.Errorf("Result: %q", result) + } + }) + } +}