Repository: Evertras/bubble-table
Pull request #71 (2022-05-03 12:19:07)

Add example of changing page size dynamically and fix edge case
Related to #69 

Shows an example of resizing pages dynamically to adjust table height.  Fixes an edge case where increasing the page size could leave the user on a page beyond the last.


Patch:
diff --git a/examples/pagination/main.go b/examples/pagination/main.go
index 93bece1..9d4317f 100644
--- a/examples/pagination/main.go
+++ b/examples/pagination/main.go
@@ -91,6 +91,14 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
 			m.tableDefault = m.tableDefault.Focused(false)
 			m.tableWithRowIndices = m.tableWithRowIndices.Focused(true)
 
+		case "u":
+			m.tableDefault = m.tableDefault.WithPageSize(m.tableDefault.PageSize() - 1)
+			m.tableWithRowIndices = m.tableWithRowIndices.WithPageSize(m.tableWithRowIndices.PageSize() - 1)
+
+		case "i":
+			m.tableDefault = m.tableDefault.WithPageSize(m.tableDefault.PageSize() + 1)
+			m.tableWithRowIndices = m.tableWithRowIndices.WithPageSize(m.tableWithRowIndices.PageSize() + 1)
+
 		case "r":
 			m.tableDefault = m.tableDefault.WithCurrentPage(rand.Intn(m.tableDefault.MaxPages()) + 1)
 			m.tableWithRowIndices = m.tableWithRowIndices.WithCurrentPage(rand.Intn(m.tableWithRowIndices.MaxPages()) + 1)
@@ -127,7 +135,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, 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")
+	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 'u' to decrease page size by 1, 'i' to increase page size by 1\nPress q or ctrl+c to quit\n\n")
 
 	pad := lipgloss.NewStyle().Padding(1)
 
diff --git a/table/options.go b/table/options.go
index d2d596a..d40a49e 100644
--- a/table/options.go
+++ b/table/options.go
@@ -130,10 +130,17 @@ func (m Model) WithStaticFooter(footer string) Model {
 	return m
 }
 
-// WithPageSize enables pagination using the given page size.
+// WithPageSize enables pagination using the given page size.  This can be called
+// again at any point to resize the height of the table.
 func (m Model) WithPageSize(pageSize int) Model {
 	m.pageSize = pageSize
 
+	maxPages := m.MaxPages()
+
+	if m.currentPage >= maxPages {
+		m.currentPage = maxPages - 1
+	}
+
 	return m
 }
 


Test patch:
diff --git a/table/pagination_test.go b/table/pagination_test.go
index 467d2da..11f2d98 100644
--- a/table/pagination_test.go
+++ b/table/pagination_test.go
@@ -388,3 +388,23 @@ func TestPaginationSetsLastPageWithFewerRows(t *testing.T) {
 
 	assert.Equal(t, 2, model.CurrentPage())
 }
+
+func TestPaginationBoundsToMaxPageOnResize(t *testing.T) {
+	const (
+		pageSize = 5
+		numRows  = 20
+	)
+
+	model := genPaginationTable(numRows, pageSize)
+
+	assert.Equal(t, model.CurrentPage(), 1)
+
+	model.pageUp()
+
+	assert.Equal(t, model.CurrentPage(), 4)
+
+	model = model.WithPageSize(10)
+
+	assert.Equal(t, model.CurrentPage(), 2)
+	assert.Equal(t, model.MaxPages(), 2)
+}