mirror of
https://github.com/charmbracelet/lipgloss.git
synced 2024-11-23 22:33:27 +03:00
fix: shared indices for first row of data and headers (StyleFunc bug) (#377)
* test(table): show differing styles between first row and headers * fix(table): remove overlapping indices for styling rows and headers * test(table): remove TestTableShrink; it's fixed on another branch * docs(table): add godoc for HeaderRow const * fix(test): use HeaderRow for table header styling
This commit is contained in:
parent
b08e7e4762
commit
f8dd5072db
@ -7,6 +7,10 @@ import (
|
|||||||
"github.com/charmbracelet/x/ansi"
|
"github.com/charmbracelet/x/ansi"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// HeaderRow denotes the header's row index used when rendering headers. Use
|
||||||
|
// this value when looking to customize header styles in StyleFunc.
|
||||||
|
const HeaderRow int = -1
|
||||||
|
|
||||||
// StyleFunc is the style function that determines the style of a Cell.
|
// StyleFunc is the style function that determines the style of a Cell.
|
||||||
//
|
//
|
||||||
// It takes the row and column of the cell as an input and determines the
|
// It takes the row and column of the cell as an input and determines the
|
||||||
@ -235,15 +239,15 @@ func (t *Table) String() string {
|
|||||||
// the StyleFunc after the headers and rows. Update the widths for a final
|
// the StyleFunc after the headers and rows. Update the widths for a final
|
||||||
// time.
|
// time.
|
||||||
for i, cell := range t.headers {
|
for i, cell := range t.headers {
|
||||||
t.widths[i] = max(t.widths[i], lipgloss.Width(t.style(0, i).Render(cell)))
|
t.widths[i] = max(t.widths[i], lipgloss.Width(t.style(HeaderRow, i).Render(cell)))
|
||||||
t.heights[0] = max(t.heights[0], lipgloss.Height(t.style(0, i).Render(cell)))
|
t.heights[0] = max(t.heights[0], lipgloss.Height(t.style(HeaderRow, i).Render(cell)))
|
||||||
}
|
}
|
||||||
|
|
||||||
for r := 0; r < t.data.Rows(); r++ {
|
for r := 0; r < t.data.Rows(); r++ {
|
||||||
for i := 0; i < t.data.Columns(); i++ {
|
for i := 0; i < t.data.Columns(); i++ {
|
||||||
cell := t.data.At(r, i)
|
cell := t.data.At(r, i)
|
||||||
|
|
||||||
rendered := t.style(r+1, i).Render(cell)
|
rendered := t.style(r, i).Render(cell)
|
||||||
t.heights[r+btoi(hasHeaders)] = max(t.heights[r+btoi(hasHeaders)], lipgloss.Height(rendered))
|
t.heights[r+btoi(hasHeaders)] = max(t.heights[r+btoi(hasHeaders)], lipgloss.Height(rendered))
|
||||||
t.widths[i] = max(t.widths[i], lipgloss.Width(rendered))
|
t.widths[i] = max(t.widths[i], lipgloss.Width(rendered))
|
||||||
}
|
}
|
||||||
@ -452,7 +456,7 @@ func (t *Table) constructHeaders() string {
|
|||||||
s.WriteString(t.borderStyle.Render(t.border.Left))
|
s.WriteString(t.borderStyle.Render(t.border.Left))
|
||||||
}
|
}
|
||||||
for i, header := range t.headers {
|
for i, header := range t.headers {
|
||||||
s.WriteString(t.style(0, i).
|
s.WriteString(t.style(HeaderRow, i).
|
||||||
MaxHeight(1).
|
MaxHeight(1).
|
||||||
Width(t.widths[i]).
|
Width(t.widths[i]).
|
||||||
MaxWidth(t.widths[i]).
|
MaxWidth(t.widths[i]).
|
||||||
@ -537,7 +541,7 @@ func (t *Table) constructRow(index int, isOverflow bool) string {
|
|||||||
cell = t.data.At(index, c)
|
cell = t.data.At(index, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
cells = append(cells, t.style(index+1, c).
|
cells = append(cells, t.style(index, c).
|
||||||
Height(height).
|
Height(height).
|
||||||
MaxHeight(height).
|
MaxHeight(height).
|
||||||
Width(t.widths[c]).
|
Width(t.widths[c]).
|
||||||
|
@ -7,11 +7,12 @@ import (
|
|||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
"github.com/charmbracelet/lipgloss"
|
||||||
"github.com/charmbracelet/x/ansi"
|
"github.com/charmbracelet/x/ansi"
|
||||||
|
"github.com/charmbracelet/x/exp/golden"
|
||||||
)
|
)
|
||||||
|
|
||||||
var TableStyle = func(row, col int) lipgloss.Style {
|
var TableStyle = func(row, col int) lipgloss.Style {
|
||||||
switch {
|
switch {
|
||||||
case row == 0:
|
case row == HeaderRow:
|
||||||
return lipgloss.NewStyle().Padding(0, 1).Align(lipgloss.Center)
|
return lipgloss.NewStyle().Padding(0, 1).Align(lipgloss.Center)
|
||||||
case row%2 == 0:
|
case row%2 == 0:
|
||||||
return lipgloss.NewStyle().Padding(0, 1)
|
return lipgloss.NewStyle().Padding(0, 1)
|
||||||
@ -65,7 +66,7 @@ func TestTableExample(t *testing.T) {
|
|||||||
BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("99"))).
|
BorderStyle(lipgloss.NewStyle().Foreground(lipgloss.Color("99"))).
|
||||||
StyleFunc(func(row, col int) lipgloss.Style {
|
StyleFunc(func(row, col int) lipgloss.Style {
|
||||||
switch {
|
switch {
|
||||||
case row == 0:
|
case row == HeaderRow:
|
||||||
return HeaderStyle
|
return HeaderStyle
|
||||||
case row%2 == 0:
|
case row%2 == 0:
|
||||||
return EvenRowStyle
|
return EvenRowStyle
|
||||||
@ -91,8 +92,8 @@ func TestTableExample(t *testing.T) {
|
|||||||
└──────────┴───────────────────────────────┴─────────────────┘
|
└──────────┴───────────────────────────────┴─────────────────┘
|
||||||
`)
|
`)
|
||||||
|
|
||||||
if table.String() != expected {
|
if got := ansi.Strip(table.String()); got != expected {
|
||||||
t.Fatalf("expected:\n\n%s\n\ngot:\n\n%s", expected, table.String())
|
t.Fatalf("expected:\n\n%s\n\ngot:\n\n%s", expected, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +527,7 @@ func TestTableRowSeparators(t *testing.T) {
|
|||||||
|
|
||||||
func TestTableHeights(t *testing.T) {
|
func TestTableHeights(t *testing.T) {
|
||||||
styleFunc := func(row, col int) lipgloss.Style {
|
styleFunc := func(row, col int) lipgloss.Style {
|
||||||
if row == 0 {
|
if row == HeaderRow {
|
||||||
return lipgloss.NewStyle().Padding(0, 1)
|
return lipgloss.NewStyle().Padding(0, 1)
|
||||||
}
|
}
|
||||||
if col == 0 {
|
if col == 0 {
|
||||||
@ -584,7 +585,7 @@ func TestTableHeights(t *testing.T) {
|
|||||||
|
|
||||||
func TestTableMultiLineRowSeparator(t *testing.T) {
|
func TestTableMultiLineRowSeparator(t *testing.T) {
|
||||||
styleFunc := func(row, col int) lipgloss.Style {
|
styleFunc := func(row, col int) lipgloss.Style {
|
||||||
if row == 0 {
|
if row == HeaderRow {
|
||||||
return lipgloss.NewStyle().Padding(0, 1)
|
return lipgloss.NewStyle().Padding(0, 1)
|
||||||
}
|
}
|
||||||
if col == 0 {
|
if col == 0 {
|
||||||
@ -1140,6 +1141,33 @@ 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
func TestClearRows(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
9
table/testdata/TestStyleFunc.golden
vendored
Normal file
9
table/testdata/TestStyleFunc.golden
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
┌──────────┬──────────────┬───────────┐
|
||||||
|
│ LANGUAGE │ FORMAL │ INFORMAL │
|
||||||
|
├──────────┼──────────────┼───────────┤
|
||||||
|
│ Chinese │ Nǐn hǎo │ Nǐ hǎo │
|
||||||
|
│ French │ Bonjour │ Salut │
|
||||||
|
│ Japanese │ こんにちは │ やあ │
|
||||||
|
│ Russian │ Zdravstvuyte │ Privet │
|
||||||
|
│ Spanish │ Hola │ ¿Qué tal? │
|
||||||
|
└──────────┴──────────────┴───────────┘
|
Loading…
Reference in New Issue
Block a user