From 2979845a5cd25c4323c012e6742217b07eab86de Mon Sep 17 00:00:00 2001 From: wheelibin Date: Tue, 2 Jun 2026 23:08:28 +0100 Subject: [PATCH] fix(#130): apply column style padding to headers and cells --- table/header.go | 10 +++++++++- table/row.go | 15 +++++++++++++-- table/view_test.go | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/table/header.go b/table/header.go index f90a401..010844a 100644 --- a/table/header.go +++ b/table/header.go @@ -29,7 +29,15 @@ func (m Model) renderHeaders() string { borderOverhead := borderStyle.GetBorderLeftSize() + borderStyle.GetBorderRightSize() style := borderStyle.Inherit(column.style).Inherit(m.baseStyle).Width(column.width + borderOverhead) - headerSection := limitStr(column.title, column.width) + // lipgloss Inherit() explicitly skips padding/margin, so apply column + // padding directly to ensure it takes effect. + colPadTop, colPadRight, colPadBottom, colPadLeft := column.style.GetPadding() + if colPadTop != 0 || colPadRight != 0 || colPadBottom != 0 || colPadLeft != 0 { + style = style.Padding(colPadTop, colPadRight, colPadBottom, colPadLeft) + } + + contentWidth := max(column.width-colPadLeft-colPadRight, 0) + headerSection := limitStr(column.title, contentWidth) return style.Render(headerSection) } diff --git a/table/row.go b/table/row.go index bb30a15..3114835 100644 --- a/table/row.go +++ b/table/row.go @@ -57,6 +57,13 @@ func (r Row) WithStyle(style lipgloss.Style) Row { func (m Model) renderRowColumnData(row Row, column Column, rowStyle lipgloss.Style, borderStyle lipgloss.Style) string { cellStyle := rowStyle.Inherit(column.style).Inherit(m.baseStyle) + // lipgloss Inherit() explicitly skips padding/margin, so apply column + // padding directly to ensure it takes effect. + colPadTop, colPadRight, colPadBottom, colPadLeft := column.style.GetPadding() + if colPadTop != 0 || colPadRight != 0 || colPadBottom != 0 || colPadLeft != 0 { + cellStyle = cellStyle.Padding(colPadTop, colPadRight, colPadBottom, colPadLeft) + } + var str string switch column.key { @@ -107,11 +114,15 @@ func (m Model) renderRowColumnData(row Row, column Column, rowStyle lipgloss.Sty } } + // Reduce the available text width by any horizontal column padding so that + // content is truncated/wrapped to the inner content area, not the full cell. + contentWidth := max(column.width-colPadLeft-colPadRight, 0) + if m.multiline { - str = ansi.Wordwrap(str, column.width, "") + str = ansi.Wordwrap(str, contentWidth, "") cellStyle = cellStyle.Align(lipgloss.Top) } else { - str = limitStr(str, column.width) + str = limitStr(str, contentWidth) } // In lipgloss v2, Width() sets the *total* outer width (including borders). diff --git a/table/view_test.go b/table/view_test.go index f48dde6..b59b0fd 100644 --- a/table/view_test.go +++ b/table/view_test.go @@ -1922,3 +1922,21 @@ func TestRowBorderNoSeparatorBeforePaddingRows(t *testing.T) { assert.Equal(t, expectedTable, rendered) } + +func TestColumnStylePaddingAppliedToHeaderAndCells(t *testing.T) { + // Regression test for https://github.com/Evertras/bubble-table/issues/130. + // lipgloss Inherit() skips padding, so column padding was silently ignored. + cols := []Column{ + NewColumn("a", "A", 10). + WithStyle(lipgloss.NewStyle().Padding(0, 1)), + } + rows := []Row{ + NewRow(RowData{"a": "hello"}), + NewRow(RowData{"a": "very long text"}), + } + + const expectedTable = "┏━━━━━━━━━━┓\n┃ A ┃\n┣━━━━━━━━━━┫\n┃ hello ┃\n┃ very lo… ┃\n┗━━━━━━━━━━┛" + + rendered := New(cols).WithRows(rows).View() + assert.Equal(t, expectedTable, rendered) +}