ratatui-org / ratatui

Rust library that's all about cooking up terminal user interfaces (TUIs) 👨‍🍳🐀
https://ratatui.rs
MIT License
8.86k stars 269 forks source link

Add .next()/.prev() to ListState to make traversing a list of selectable items easier #1156

Open sparky8251 opened 1 month ago

sparky8251 commented 1 month ago

Problem

When using a ListState to display selectable items in a TUI, there is no easy way to advance the selection right now requiring a wrapper struct to handle it currently.

Solution

As an example, this is the wrapper code I've been using

#[derive(Debug, Default)]
pub struct StatefulList<T> {
    state: ListState,
    items: Vec<T>,
}

impl<T> StatefulList<T> {
    pub fn with_items(items: Vec<T>) -> Self {
        Self {
            state: ListState::default(),
            items,
        }
    }
    pub fn next(&mut self) {
        let i = match self.state.selected() {
            Some(i) => {
                if i >= self.items.len() - 1 {
                    0
                } else {
                    i + 1
                }
            }
            None => 0,
        };
        self.state.select(Some(i));
    }
    pub fn previous(&mut self) {
        let i = match self.state.selected() {
            Some(i) => {
                if i == 0 {
                    self.items.len() - 1
                } else {
                    i - 1
                }
            }
            None => 0,
        };
        self.state.select(Some(i));
    }
}

But if ListState just had .next()/.prev() implemented on it, I wouldn't need this code at all.

Additional context

It's likely other stateful widgets that are often used to make selectable "lists" would benefit from similar functions, but I'm not sure which ones exist and are missing them as of right now.

hexavik commented 3 weeks ago

Hi, can I take this?

orhun commented 3 weeks ago

@hexavik you got it!

hexavik commented 3 weeks ago

Thanks, I shall start working on this from Monday.

joshka commented 3 weeks ago

Already in flight - https://github.com/ratatui-org/ratatui/pull/1159