Skip to content

Commit

Permalink
Add programmatic options for pagination controls (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
Evertras authored Apr 6, 2022
1 parent c54ce22 commit ceafdce
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
7 changes: 6 additions & 1 deletion examples/pagination/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"log"
"math/rand"
"strings"

tea "github.com/charmbracelet/bubbletea"
Expand Down Expand Up @@ -90,6 +91,10 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.tableDefault = m.tableDefault.Focused(false)
m.tableWithRowIndices = m.tableWithRowIndices.Focused(true)

case "r":
m.tableDefault = m.tableDefault.WithCurrentPage(rand.Intn(m.tableDefault.MaxPages()) + 1)
m.tableWithRowIndices = m.tableWithRowIndices.WithCurrentPage(rand.Intn(m.tableWithRowIndices.MaxPages()) + 1)

case "z":
if m.rowCount < 10 {
break
Expand Down Expand Up @@ -122,7 +127,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m Model) View() string {
body := strings.Builder{}

body.WriteString("Table demo with pagination! Press left/right to move pages, or use page up/down\nPress 'a' for left table, 'b' for right table\nPress 'z' to reduce rows by 10, 'y' to increase rows by 10\nPress q or ctrl+c to quit\n\n")
body.WriteString("Table demo with pagination! Press left/right to move pages, or use page up/down, or 'r' to jump to a random page\nPress 'a' for left table, 'b' for right table\nPress 'z' to reduce rows by 10, 'y' to increase rows by 10\nPress q or ctrl+c to quit\n\n")

pad := lipgloss.NewStyle().Padding(1)

Expand Down
54 changes: 54 additions & 0 deletions table/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,57 @@ func (m Model) WithTargetWidth(totalWidth int) Model {

return m
}

// PageDown goes to the next page of a paginated table, wrapping to the first
// page if the table is already on the last page.
func (m Model) PageDown() Model {
m.pageDown()

return m
}

// PageUp goes to the previous page of a paginated table, wrapping to the
// last page if the table is already on the first page.
func (m Model) PageUp() Model {
m.pageUp()

return m
}

// PageLast goes to the last page of a paginated table.
func (m Model) PageLast() Model {
m.pageLast()

return m
}

// PageFirst goes to the first page of a paginated table.
func (m Model) PageFirst() Model {
m.pageFirst()

return m
}

// WithCurrentPage sets the current page (1 as the first page) of a paginated
// table, bounded to the total number of pages. The current selected row will
// be set to the top row of the page if the page changed.
func (m Model) WithCurrentPage(currentPage int) Model {
if m.pageSize == 0 || currentPage == m.CurrentPage() {
return m
}

if currentPage < 1 {
currentPage = 1
} else {
maxPages := m.MaxPages()

if currentPage > maxPages {
currentPage = maxPages
}
}

m.currentPage = currentPage - 1
m.rowCursorIndex = m.currentPage * m.pageSize

return m
}
68 changes: 68 additions & 0 deletions table/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,71 @@ func TestWithHighlightedRowSetTooHigh(t *testing.T) {

assert.Equal(t, model.rows[1], model.HighlightedRow())
}

// This is long only because it's a lot of repetitive test cases
// nolint: funlen
func TestPageOptions(t *testing.T) {
const (
pageSize = 5
rowCount = 30
)

cols := []Column{
NewColumn("id", "ID", 3),
}

rows := make([]Row, rowCount)

model := New(cols).WithRows(rows).WithPageSize(pageSize)
assert.Equal(t, 1, model.CurrentPage())

model = model.PageDown()
assert.Equal(t, 2, model.CurrentPage())

model = model.PageDown()
model = model.PageUp()
assert.Equal(t, 2, model.CurrentPage())

model = model.PageLast()
assert.Equal(t, 6, model.CurrentPage())

model = model.PageLast()
model = model.PageLast()
assert.Equal(t, 6, model.CurrentPage())

model = model.PageFirst()
assert.Equal(t, 1, model.CurrentPage())

model = model.PageFirst()
model = model.PageFirst()
assert.Equal(t, 1, model.CurrentPage())

model = model.PageUp()
assert.Equal(t, 6, model.CurrentPage())

model = model.PageDown()
assert.Equal(t, 1, model.CurrentPage())

model = model.WithCurrentPage(3)
model = model.WithCurrentPage(3)
model = model.WithCurrentPage(3)
assert.Equal(t, 3, model.CurrentPage())
assert.Equal(t, 10, model.rowCursorIndex)

model = model.WithCurrentPage(-1)
assert.Equal(t, 1, model.CurrentPage())
assert.Equal(t, 0, model.rowCursorIndex)

model = model.WithCurrentPage(0)
assert.Equal(t, 1, model.CurrentPage())
assert.Equal(t, 0, model.rowCursorIndex)

model = model.WithCurrentPage(7)
assert.Equal(t, 6, model.CurrentPage())
assert.Equal(t, 25, model.rowCursorIndex)

model.rowCursorIndex = 26
model = model.WithCurrentPage(6)
assert.Equal(t, 6, model.CurrentPage())
assert.Equal(t, 26, model.rowCursorIndex)
}

0 comments on commit ceafdce

Please sign in to comment.