refactor(table): get data from lipgloss instead of storing it separately

This commit is contained in:
Andrey Nering
2025-05-29 17:27:54 -03:00
parent 82a5f275cf
commit 2110223809
2 changed files with 38 additions and 41 deletions
+18 -21
View File
@@ -16,8 +16,6 @@ type Model struct {
KeyMap KeyMap KeyMap KeyMap
Help help.Model Help help.Model
headers []string
rows [][]string
cursor int cursor int
focus bool focus bool
styles Styles styles Styles
@@ -121,19 +119,13 @@ func DefaultStyles() Styles {
// NewFromTemplate lets you create a table [Model] from Lip Gloss' // NewFromTemplate lets you create a table [Model] from Lip Gloss'
// [table.Table]. // [table.Table].
func NewFromTemplate(t *table.Table, headers []string, rows [][]string) *Model { func NewFromTemplate(t *table.Table, headers []string, rows [][]string) *Model {
m := &Model{ return &Model{
cursor: 0, cursor: 0,
KeyMap: DefaultKeyMap(), KeyMap: DefaultKeyMap(),
Help: help.New(), Help: help.New(),
table: t, table: t,
useStyleFunc: true, 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 // 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. // SetHeaders sets the table headers.
func (m *Model) SetHeaders(headers ...string) *Model { func (m *Model) SetHeaders(headers ...string) *Model {
m.headers = headers
m.table.Headers(headers...) m.table.Headers(headers...)
return m return m
} }
// SetRows sets the table rows. // SetRows sets the table rows.
func (m *Model) SetRows(rows ...[]string) *Model { func (m *Model) SetRows(rows ...[]string) *Model {
m.rows = rows
m.table.Rows(rows...) m.table.Rows(rows...)
return m return m
} }
// SetCursor sets the cursor position in the table. // SetCursor sets the cursor position in the table.
func (m *Model) SetCursor(n int) *Model { 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 return m
} }
@@ -347,7 +337,7 @@ func (m *Model) SetWidth(w int) *Model {
// SetYOffset sets the YOffset position in the table. // SetYOffset sets the YOffset position in the table.
func (m *Model) SetYOffset(n int) *Model { 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) m.table.YOffset(m.yOffset)
return m return m
} }
@@ -377,9 +367,11 @@ func (m *Model) OverwriteStyles(s Styles) *Model {
// OverwriteStylesFromLipgloss sets the [Model]'s style attributes from an // OverwriteStylesFromLipgloss sets the [Model]'s style attributes from an
// existing [lipgloss.Table]. // existing [lipgloss.Table].
func (m *Model) OverwriteStylesFromLipgloss(t *table.Table) { func (m *Model) OverwriteStylesFromLipgloss(t *table.Table) {
t.Rows(m.rows...) var (
t.Headers(m.headers...) previousHeaders = m.table.GetHeaders()
m.table = t previousData = m.table.GetData()
)
m.table = t.Headers(previousHeaders...).Data(previousData)
m.useStyleFunc = true m.useStyleFunc = true
} }
@@ -502,12 +494,17 @@ func (m Model) Focused() bool {
// Rows returns the current rows. // Rows returns the current rows.
func (m Model) Rows() [][]string { 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. // Headers returns the current headers.
func (m Model) Headers() []string { func (m Model) Headers() []string {
return m.headers return m.table.GetHeaders()
} }
// Cursor returns the index of the selected row. // 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 // SelectedRow returns the selected row. You can cast it to your own
// implementation. // implementation.
func (m Model) SelectedRow() []string { 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 nil
} }
return m.rows[m.cursor] return table.DataToMatrix(m.table.GetData())[m.cursor]
} }
// Movement // Movement
@@ -550,7 +547,7 @@ func (m *Model) GotoTop() {
// GotoBottom moves the selection to the last row. // GotoBottom moves the selection to the last row.
func (m *Model) GotoBottom() { func (m *Model) GotoBottom() {
m.MoveDown(len(m.rows)) m.MoveDown(m.RowCount())
} }
// Helpers // Helpers
+20 -20
View File
@@ -74,8 +74,8 @@ func TestModel_FromValues(t *testing.T) {
[]string{"foo3", "bar3"}, []string{"foo3", "bar3"},
)) ))
if len(table.rows) != 3 { if table.RowCount() != 3 {
t.Fatalf("expect table to have 3 rows but it has %d", len(table.rows)) t.Fatalf("expect table to have 3 rows but it has %d", table.RowCount())
} }
expect := [][]string{ expect := [][]string{
@@ -83,8 +83,8 @@ func TestModel_FromValues(t *testing.T) {
{"foo2", "bar2"}, {"foo2", "bar2"},
{"foo3", "bar3"}, {"foo3", "bar3"},
} }
if !reflect.DeepEqual(table.rows, expect) { if !reflect.DeepEqual(table.Rows(), expect) {
t.Fatalf("\n\nwant %v\n\ngot %v", expect, table.rows) 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 { if table.RowCount() != 2 {
t.Fatalf("expect table to have 2 rows but it has %d", len(table.rows)) t.Fatalf("expect table to have 2 rows but it has %d", table.RowCount())
} }
expect := [][]string{ expect := [][]string{
{"foo1.", "bar1"}, {"foo1.", "bar1"},
{"foo,bar,baz", "bar,2"}, {"foo,bar,baz", "bar,2"},
} }
if !reflect.DeepEqual(table.rows, expect) { if !reflect.DeepEqual(table.Rows(), expect) {
t.Fatalf("\n\nwant %v\n\ngot %v", expect, table.rows) t.Fatalf("\n\nwant %v\n\ngot %v", expect, table.Rows())
} }
t.Run("new with options", func(t *testing.T) { t.Run("new with options", func(t *testing.T) {
tb := New( tb := New(
@@ -606,38 +606,38 @@ func TestCursorNavigation(t *testing.T) {
func TestModel_SetRows(t *testing.T) { func TestModel_SetRows(t *testing.T) {
table := New(WithHeaders("col1", "col2", "col3")) table := New(WithHeaders("col1", "col2", "col3"))
if len(table.rows) != 0 { if table.RowCount() != 0 {
t.Fatalf("want 0, got %d", len(table.rows)) t.Fatalf("want 0, got %d", table.RowCount())
} }
table.SetRows([]string{"r1"}, []string{"r2"}) table.SetRows([]string{"r1"}, []string{"r2"})
if len(table.rows) != 2 { if table.RowCount() != 2 {
t.Fatalf("want 2, got %d", len(table.rows)) t.Fatalf("want 2, got %d", table.RowCount())
} }
want := [][]string{{"r1"}, {"r2"}} want := [][]string{{"r1"}, {"r2"}}
if !reflect.DeepEqual(table.rows, want) { if !reflect.DeepEqual(table.Rows(), want) {
t.Fatalf("\n\nwant %v\n\ngot %v", want, table.rows) t.Fatalf("\n\nwant %v\n\ngot %v", want, table.Rows())
} }
} }
func TestModel_SetHeaders(t *testing.T) { func TestModel_SetHeaders(t *testing.T) {
table := New() table := New()
if len(table.headers) != 0 { if len(table.Headers()) != 0 {
t.Fatalf("want 0, got %d", len(table.headers)) t.Fatalf("want 0, got %d", len(table.Headers()))
} }
table.SetHeaders("Foo", "Bar") table.SetHeaders("Foo", "Bar")
if len(table.headers) != 2 { if len(table.Headers()) != 2 {
t.Fatalf("want 2, got %d", len(table.headers)) t.Fatalf("want 2, got %d", len(table.Headers()))
} }
want := []string{"Foo", "Bar"} want := []string{"Foo", "Bar"}
if !reflect.DeepEqual(table.headers, want) { if !reflect.DeepEqual(table.Headers(), want) {
t.Fatalf("\n\nwant %v\n\ngot %v", want, table.headers) t.Fatalf("\n\nwant %v\n\ngot %v", want, table.Headers())
} }
} }