From d8581323b63a3bb43c6d5247a00353d7cbd1d236 Mon Sep 17 00:00:00 2001 From: bashbunni <15822994+bashbunni@users.noreply.github.com> Date: Mon, 21 Oct 2024 09:00:40 -0700 Subject: [PATCH] fix(table): include margins in cell width (#401) * test(table): modify test to show bug * fix(table): account for margin in cell height and width * test(table): add sizing tests for margins and padding * test(table): move TestSizing to another branch * chore: tidy + force truecolor in test * chore(lint): remove nil check on []string --- table/table.go | 8 +- table/table_test.go | 75 +++++++++++++------ .../margin_and_padding_set.golden | 29 +++++++ .../right-aligned_text_with_margins.golden} | 8 +- 4 files changed, 90 insertions(+), 30 deletions(-) create mode 100644 table/testdata/TestStyleFunc/margin_and_padding_set.golden rename table/testdata/{TestStyleFunc.golden => TestStyleFunc/right-aligned_text_with_margins.golden} (69%) diff --git a/table/table.go b/table/table.go index f5c47155..2a970ffc 100644 --- a/table/table.go +++ b/table/table.go @@ -552,10 +552,12 @@ func (t *Table) constructRow(index int, isOverflow bool) string { cell = t.data.At(index, c) } - cells = append(cells, t.style(index, c). - Height(height). + cellStyle := t.style(index, c) + cells = append(cells, cellStyle. + // Account for the margins in the cell sizing. + Height(height-cellStyle.GetVerticalMargins()). MaxHeight(height). - Width(t.widths[c]). + Width(t.widths[c]-cellStyle.GetHorizontalMargins()). MaxWidth(t.widths[c]). Render(ansi.Truncate(cell, cellWidth*height, "…"))) diff --git a/table/table_test.go b/table/table_test.go index 09175eb2..ce4c8fb4 100644 --- a/table/table_test.go +++ b/table/table_test.go @@ -8,6 +8,7 @@ import ( "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/x/ansi" "github.com/charmbracelet/x/exp/golden" + "github.com/muesli/termenv" ) var TableStyle = func(row, col int) lipgloss.Style { @@ -1142,30 +1143,58 @@ func TestTableHeightWithOffset(t *testing.T) { } func TestStyleFunc(t *testing.T) { - TestStyle := func(row, col int) lipgloss.Style { - switch { - // this is the header - case row == HeaderRow: - return lipgloss.NewStyle().Align(lipgloss.Center) - // this is the first row of data - case row == 0: - return lipgloss.NewStyle().Padding(0, 1).Align(lipgloss.Right) - default: - return lipgloss.NewStyle().Padding(0, 1) - } + lipgloss.SetColorProfile(termenv.TrueColor) + tests := []struct { + name string + style StyleFunc + }{ + { + "right-aligned text with margins", + func(row, col int) lipgloss.Style { + switch { + case row == HeaderRow: + return lipgloss.NewStyle().Align(lipgloss.Center) + default: + return lipgloss.NewStyle().Margin(0, 1).Align(lipgloss.Right) + } + }, + }, + { + "margin and padding set", + // this test case uses background colors to differentiate margins + // and padding. + func(row, col int) lipgloss.Style { + switch { + case row == HeaderRow: + return lipgloss.NewStyle().Align(lipgloss.Center) + default: + return lipgloss.NewStyle(). + Padding(1). + Margin(1). + // keeping right-aligned text as it's the most likely to + // be broken when truncated. + Align(lipgloss.Right). + Background(lipgloss.Color("#874bfc")) + } + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + table := New(). + Border(lipgloss.NormalBorder()). + StyleFunc(tc.style). + Headers("LANGUAGE", "FORMAL", "INFORMAL"). + Row("Chinese", "Nǐn hǎo", "Nǐ hǎo"). + Row("French", "Bonjour", "Salut"). + Row("Japanese", "こんにちは", "やあ"). + Row("Russian", "Zdravstvuyte", "Privet"). + Row("Spanish", "Hola", "¿Qué tal?") + + golden.RequireEqual(t, []byte(table.String())) + }) } - - table := New(). - Border(lipgloss.NormalBorder()). - StyleFunc(TestStyle). - Headers("LANGUAGE", "FORMAL", "INFORMAL"). - Row("Chinese", "Nǐn hǎo", "Nǐ hǎo"). - Row("French", "Bonjour", "Salut"). - Row("Japanese", "こんにちは", "やあ"). - Row("Russian", "Zdravstvuyte", "Privet"). - Row("Spanish", "Hola", "¿Qué tal?") - - golden.RequireEqual(t, []byte(table.String())) } func TestClearRows(t *testing.T) { diff --git a/table/testdata/TestStyleFunc/margin_and_padding_set.golden b/table/testdata/TestStyleFunc/margin_and_padding_set.golden new file mode 100644 index 00000000..00cecd43 --- /dev/null +++ b/table/testdata/TestStyleFunc/margin_and_padding_set.golden @@ -0,0 +1,29 @@ +┌────────────┬────────────────┬─────────────┐ +│ LANGUAGE │ FORMAL │ INFORMAL │ +├────────────┼────────────────┼─────────────┤ +│ │ │ │ +│   │   │   │ +│   Chinese  │   Nǐn hǎo  │   Nǐ hǎo  │ +│   │   │   │ +│ │ │ │ +│ │ │ │ +│   │   │   │ +│   French  │   Bonjour  │   Salut  │ +│   │   │   │ +│ │ │ │ +│ │ │ │ +│   │   │   │ +│  Japanese  │   こんにちは  │   やあ  │ +│   │   │   │ +│ │ │ │ +│ │ │ │ +│   │   │   │ +│   Russian  │  Zdravstvuyte  │   Privet  │ +│   │   │   │ +│ │ │ │ +│ │ │ │ +│   │   │   │ +│   Spanish  │   Hola  │  ¿Qué tal?  │ +│   │   │   │ +│ │ │ │ +└────────────┴────────────────┴─────────────┘ \ No newline at end of file diff --git a/table/testdata/TestStyleFunc.golden b/table/testdata/TestStyleFunc/right-aligned_text_with_margins.golden similarity index 69% rename from table/testdata/TestStyleFunc.golden rename to table/testdata/TestStyleFunc/right-aligned_text_with_margins.golden index e81cb45b..60e6d3c1 100644 --- a/table/testdata/TestStyleFunc.golden +++ b/table/testdata/TestStyleFunc/right-aligned_text_with_margins.golden @@ -2,8 +2,8 @@ │ LANGUAGE │ FORMAL │ INFORMAL │ ├──────────┼──────────────┼───────────┤ │ Chinese │ Nǐn hǎo │ Nǐ hǎo │ -│ French │ Bonjour │ Salut │ -│ Japanese │ こんにちは │ やあ │ -│ Russian │ Zdravstvuyte │ Privet │ -│ Spanish │ Hola │ ¿Qué tal? │ +│ French │ Bonjour │ Salut │ +│ Japanese │ こんにちは │ やあ │ +│ Russian │ Zdravstvuyte │ Privet │ +│ Spanish │ Hola │ ¿Qué tal? │ └──────────┴──────────────┴───────────┘ \ No newline at end of file