diff --git a/table/table.go b/table/table.go index afd7e89..0e80154 100644 --- a/table/table.go +++ b/table/table.go @@ -16,8 +16,6 @@ type Model struct { KeyMap KeyMap Help help.Model - headers []string - rows [][]string cursor int focus bool styles Styles @@ -121,19 +119,13 @@ func DefaultStyles() Styles { // NewFromTemplate lets you create a table [Model] from Lip Gloss' // [table.Table]. func NewFromTemplate(t *table.Table, headers []string, rows [][]string) *Model { - m := &Model{ + return &Model{ cursor: 0, KeyMap: DefaultKeyMap(), Help: help.New(), table: t, useStyleFunc: true, } - // We can't get the rows and headers from the table, so the user needs to - // provide them as arguments. - m.rows = rows - m.headers = headers - - return m } // SetBorder is a shorthand function for setting or unsetting borders on a @@ -313,21 +305,19 @@ func WithKeyMap(km KeyMap) Option { // SetHeaders sets the table headers. func (m *Model) SetHeaders(headers ...string) *Model { - m.headers = headers m.table.Headers(headers...) return m } // SetRows sets the table rows. func (m *Model) SetRows(rows ...[]string) *Model { - m.rows = rows m.table.Rows(rows...) return m } // SetCursor sets the cursor position in the table. func (m *Model) SetCursor(n int) *Model { - m.cursor = clamp(n, 0, len(m.rows)-1) + m.cursor = clamp(n, 0, m.RowCount()-1) return m } @@ -347,7 +337,7 @@ func (m *Model) SetWidth(w int) *Model { // SetYOffset sets the YOffset position in the table. func (m *Model) SetYOffset(n int) *Model { - m.yOffset = clamp(n, 0, len(m.rows)-1) + m.yOffset = clamp(n, 0, m.RowCount()-1) m.table.YOffset(m.yOffset) return m } @@ -377,9 +367,11 @@ func (m *Model) OverwriteStyles(s Styles) *Model { // OverwriteStylesFromLipgloss sets the [Model]'s style attributes from an // existing [lipgloss.Table]. func (m *Model) OverwriteStylesFromLipgloss(t *table.Table) { - t.Rows(m.rows...) - t.Headers(m.headers...) - m.table = t + var ( + previousHeaders = m.table.GetHeaders() + previousData = m.table.GetData() + ) + m.table = t.Headers(previousHeaders...).Data(previousData) m.useStyleFunc = true } @@ -502,12 +494,17 @@ func (m Model) Focused() bool { // Rows returns the current rows. func (m Model) Rows() [][]string { - return m.rows + return table.DataToMatrix(m.table.GetData()) +} + +// RowCount returns the number of rows in the table. +func (m Model) RowCount() int { + return m.table.GetData().Rows() } // Headers returns the current headers. func (m Model) Headers() []string { - return m.headers + return m.table.GetHeaders() } // Cursor returns the index of the selected row. @@ -518,11 +515,11 @@ func (m Model) Cursor() int { // SelectedRow returns the selected row. You can cast it to your own // implementation. func (m Model) SelectedRow() []string { - if m.cursor < 0 || m.cursor >= len(m.rows) { + if m.cursor < 0 || m.cursor >= m.RowCount() { return nil } - return m.rows[m.cursor] + return table.DataToMatrix(m.table.GetData())[m.cursor] } // Movement @@ -550,7 +547,7 @@ func (m *Model) GotoTop() { // GotoBottom moves the selection to the last row. func (m *Model) GotoBottom() { - m.MoveDown(len(m.rows)) + m.MoveDown(m.RowCount()) } // Helpers diff --git a/table/table_test.go b/table/table_test.go index fe2cbc7..606ff9a 100644 --- a/table/table_test.go +++ b/table/table_test.go @@ -74,8 +74,8 @@ func TestModel_FromValues(t *testing.T) { []string{"foo3", "bar3"}, )) - if len(table.rows) != 3 { - t.Fatalf("expect table to have 3 rows but it has %d", len(table.rows)) + if table.RowCount() != 3 { + t.Fatalf("expect table to have 3 rows but it has %d", table.RowCount()) } expect := [][]string{ @@ -83,8 +83,8 @@ func TestModel_FromValues(t *testing.T) { {"foo2", "bar2"}, {"foo3", "bar3"}, } - if !reflect.DeepEqual(table.rows, expect) { - t.Fatalf("\n\nwant %v\n\ngot %v", expect, table.rows) + if !reflect.DeepEqual(table.Rows(), expect) { + t.Fatalf("\n\nwant %v\n\ngot %v", expect, table.Rows()) } } @@ -97,16 +97,16 @@ func TestModel_FromValues_WithTabSeparator(t *testing.T) { ), ) - if len(table.rows) != 2 { - t.Fatalf("expect table to have 2 rows but it has %d", len(table.rows)) + if table.RowCount() != 2 { + t.Fatalf("expect table to have 2 rows but it has %d", table.RowCount()) } expect := [][]string{ {"foo1.", "bar1"}, {"foo,bar,baz", "bar,2"}, } - if !reflect.DeepEqual(table.rows, expect) { - t.Fatalf("\n\nwant %v\n\ngot %v", expect, table.rows) + if !reflect.DeepEqual(table.Rows(), expect) { + t.Fatalf("\n\nwant %v\n\ngot %v", expect, table.Rows()) } t.Run("new with options", func(t *testing.T) { tb := New( @@ -606,38 +606,38 @@ func TestCursorNavigation(t *testing.T) { func TestModel_SetRows(t *testing.T) { table := New(WithHeaders("col1", "col2", "col3")) - if len(table.rows) != 0 { - t.Fatalf("want 0, got %d", len(table.rows)) + if table.RowCount() != 0 { + t.Fatalf("want 0, got %d", table.RowCount()) } table.SetRows([]string{"r1"}, []string{"r2"}) - if len(table.rows) != 2 { - t.Fatalf("want 2, got %d", len(table.rows)) + if table.RowCount() != 2 { + t.Fatalf("want 2, got %d", table.RowCount()) } want := [][]string{{"r1"}, {"r2"}} - if !reflect.DeepEqual(table.rows, want) { - t.Fatalf("\n\nwant %v\n\ngot %v", want, table.rows) + if !reflect.DeepEqual(table.Rows(), want) { + t.Fatalf("\n\nwant %v\n\ngot %v", want, table.Rows()) } } func TestModel_SetHeaders(t *testing.T) { table := New() - if len(table.headers) != 0 { - t.Fatalf("want 0, got %d", len(table.headers)) + if len(table.Headers()) != 0 { + t.Fatalf("want 0, got %d", len(table.Headers())) } table.SetHeaders("Foo", "Bar") - if len(table.headers) != 2 { - t.Fatalf("want 2, got %d", len(table.headers)) + if len(table.Headers()) != 2 { + t.Fatalf("want 2, got %d", len(table.Headers())) } want := []string{"Foo", "Bar"} - if !reflect.DeepEqual(table.headers, want) { - t.Fatalf("\n\nwant %v\n\ngot %v", want, table.headers) + if !reflect.DeepEqual(table.Headers(), want) { + t.Fatalf("\n\nwant %v\n\ngot %v", want, table.Headers()) } }