17 releases (7 breaking)

new 0.9.0 May 11, 2024
0.8.2 Feb 29, 2024
0.6.0 Dec 23, 2023
0.5.0 Oct 28, 2023
0.2.2 May 3, 2023

#116 in Command-line interface

Download history 19/week @ 2024-01-21 2/week @ 2024-01-28 7/week @ 2024-02-04 134/week @ 2024-02-11 177/week @ 2024-02-18 282/week @ 2024-02-25 22/week @ 2024-03-03 52/week @ 2024-03-10 18/week @ 2024-03-17 8/week @ 2024-03-24 125/week @ 2024-03-31 24/week @ 2024-04-07 247/week @ 2024-04-14 36/week @ 2024-04-21 175/week @ 2024-04-28 182/week @ 2024-05-05

648 downloads per month
Used in 3 crates

MIT license

620KB
595 lines

A versatile widget list for Ratatui

Continuous Integration

This crate provides a stateful widget List implementation for Ratatui, enabling listing widgets that implement the PreRender trait. The associated ListState, offers functionalities such as navigating to the next and previous items. Additionally, the lists support both horizontal and vertical scrolling.

Configuration

The List can be customized with the following options:

You can adjust the behavior of ListState with the following options:

  • ListState::circular: Determines if the selection is circular. When enabled, selecting the last item loops back to the first. Enabled by default.

Example

use ratatui::prelude::*;
use tui_widget_list::{List, ListState, PreRender, PreRenderContext};

#[derive(Debug, Clone)]
pub struct ListItem {
    text: String,
    style: Style,
}

impl ListItem {
    pub fn new<T: Into<String>>(text: T) -> Self {
        Self {
            text: text.into(),
            style: Style::default(),
        }
    }
}

impl PreRender for ListItem {
   fn pre_render(&mut self, context: &PreRenderContext) -> u16 {
       // Set alternating styles
       if context.index % 2 == 0 {
           self.style = Style::default().bg(Color::Rgb(28, 28, 32));
       } else {
           self.style = Style::default().bg(Color::Rgb(0, 0, 0));
       }

       // Highlight the selected widget
       if context.is_selected {
           self.style = Style::default()
               .bg(Color::Rgb(255, 153, 0))
               .fg(Color::Rgb(28, 28, 32));
       };

       // Example: set main axis size to 1
       let main_axis_size = 1;

       main_axis_size
   }
}

impl Widget for ListItem {
    fn render(self, area: Rect, buf: &mut Buffer) {
        Line::from(self.text).style(self.style).render(area, buf);
    }
}

pub fn render(f: &mut Frame) {
    let list = List::new(vec![
        ListItem::new("Item 1"),
        ListItem::new("Item 2"),
    ]);
    let mut state = ListState::default();
    f.render_stateful_widget(list, f.size(), &mut state);
}

Long lists

tui-widget-list also allows to render long lists with thousands of items efficiently. Check out the example for demonstration. Note that the key is to create the items only once and implement Widget and PreRender on the references to the list item.

For more examples see tui-widget-list.

Documentation

docs.rs

Demos

Simple list with alternating colors

Vertically and horizontally scrollable

Dependencies

~6–11MB
~116K SLoC