From 19c85ee6837fb881478d4243e234e378dffbda6c Mon Sep 17 00:00:00 2001 From: Samuel Recker Date: Wed, 10 Sep 2025 12:17:44 +0200 Subject: [PATCH 1/2] fix: include borders in width calculation --- style.go | 4 +++- style_test.go | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/style.go b/style.go index 7e962a4f..8ab82173 100644 --- a/style.go +++ b/style.go @@ -364,7 +364,9 @@ func (s Style) Render(strs ...string) string { // Word wrap if !inline && width > 0 { - wrapAt := width - leftPadding - rightPadding + // Include border widths in available inner width so that the + // overall rendered width (including borders) matches the set width. + wrapAt := width - leftPadding - rightPadding - s.GetHorizontalBorderSize() str = cellbuf.Wrap(str, wrapAt, "") } diff --git a/style_test.go b/style_test.go index 0db740b4..8d2e0a9c 100644 --- a/style_test.go +++ b/style_test.go @@ -590,3 +590,22 @@ func TestCarriageReturnInRender(t *testing.T) { t.Fatalf("got(string):\n%s\nwant(string):\n%s", got, want) } } + +func TestWidthIncludesBorders(t *testing.T) { + s := NewStyle().BorderStyle(NormalBorder()).Width(10) + out := s.Render("hi") + if w := Width(out); w != 10 { + t.Fatalf("expected total width 10, got %d. Output: %s", w, out) + } +} + +func TestWidthIncludesBordersWithPadding(t *testing.T) { + s := NewStyle(). + BorderStyle(NormalBorder()). + Padding(1, 2, 1, 3). + Width(20) + out := s.Render("hello") + if w := Width(out); w != 20 { + t.Fatalf("expected total width 20, got %d. Output: %s", w, out) + } +} From 539ce7104c8fb98030cd81cf3cea7222ca27847b Mon Sep 17 00:00:00 2001 From: Samuel Recker Date: Wed, 10 Sep 2025 13:04:47 +0200 Subject: [PATCH 2/2] fix bug in align text --- style.go | 12 ++++++++---- style_test.go | 10 +++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/style.go b/style.go index 8ab82173..189f5b44 100644 --- a/style.go +++ b/style.go @@ -364,10 +364,12 @@ func (s Style) Render(strs ...string) string { // Word wrap if !inline && width > 0 { - // Include border widths in available inner width so that the - // overall rendered width (including borders) matches the set width. + // Include padding and border widths in available inner width so the + // overall rendered width (including borders and padding) matches Width. wrapAt := width - leftPadding - rightPadding - s.GetHorizontalBorderSize() - str = cellbuf.Wrap(str, wrapAt, "") + if wrapAt > 0 { + str = cellbuf.Wrap(str, wrapAt, "") + } } // Render core text @@ -439,7 +441,9 @@ func (s Style) Render(strs ...string) string { if colorWhitespace || styleWhitespace { st = &teWhitespace } - str = alignTextHorizontal(str, horizontalAlign, width, st) + // Align to the inner width, excluding borders (padding already applied). + innerWidth := max(0, width-s.GetHorizontalBorderSize()) + str = alignTextHorizontal(str, horizontalAlign, innerWidth, st) } } diff --git a/style_test.go b/style_test.go index 8d2e0a9c..f0ad25f4 100644 --- a/style_test.go +++ b/style_test.go @@ -593,7 +593,7 @@ func TestCarriageReturnInRender(t *testing.T) { func TestWidthIncludesBorders(t *testing.T) { s := NewStyle().BorderStyle(NormalBorder()).Width(10) - out := s.Render("hi") + out := s.Render("12345678901234567890") if w := Width(out); w != 10 { t.Fatalf("expected total width 10, got %d. Output: %s", w, out) } @@ -603,9 +603,9 @@ func TestWidthIncludesBordersWithPadding(t *testing.T) { s := NewStyle(). BorderStyle(NormalBorder()). Padding(1, 2, 1, 3). - Width(20) - out := s.Render("hello") - if w := Width(out); w != 20 { - t.Fatalf("expected total width 20, got %d. Output: %s", w, out) + Width(10) + out := s.Render("12345678901234567890") + if w := Width(out); w != 10 { + t.Fatalf("expected total width 10, got %d. Output: %s", w, out) } }