charmbracelet / bubbles

TUI components for Bubble Tea 🫧
MIT License
5.36k stars 252 forks source link

Display area slides after pagenation enabled while list runnning. #405

Open tbistr opened 1 year ago

tbistr commented 1 year ago

Describe the bug I added items to list while list model running. Then, display area slides 1 line to upper. Selected item (or once selected items) is displayed properly.

Setup Please complete the following information along with version numbers, if applicable.

To Reproduce I little modify bubbletea/example/list-sample/main.go. This program appends items each 1 seccond. When items overflow a page, the display area slides.

Source Code This not run on go playground. https://go.dev/play/p/RLjPz27-lxx

Expected behavior Display area will not slide, and index will saved each additions.

Screenshots list_bug

tbistr commented 1 year ago

additional comments

naglis commented 1 year ago

IIUC there is a bug here when SetItems() (or other method which modifies items and calls updatePagination()) would result in the pagination being shown (or hidden, if items are being removed?), we subtract pagination height from availHeight using current paginator state and paginator's PerPage and TotalPages are only updated afterwards: https://github.com/charmbracelet/bubbles/blob/95d7be54d9d4cdd73cd36e31e64b67965d517d68/list/list.go#L745-L751

So, e.g. if we already have 5 items in the list and have height available for 5 items (pagination is currently not shown) and then do SetItems(...) with 6 items (which would cause pagination to be shown), we would only subtract 1 (paginationView() height when there is only one page) instead of 2 (paginationView() height when there are more pages - it has an extra margin of 1) here because paginator per page/total pages is only updated later, so we assume we have more height than we actually have.

0xBADDCAFE commented 5 months ago

As a workaround, it seems that setting the correct height can be achieved by executing m.list.SetHeight(m.list.Height()) after cmd := m.list.SetItems(listItems). Here, m is tea.Model, and m.list is list.Model.