Struct List

Source
pub struct List<'a> { /* private fields */ }
Expand description

A widget to display several items among which one can be selected (optional)

A list is a collection of ListItems.

This is different from a Table because it does not handle columns, headers or footers and the item’s height is automatically determined. A List can also be put in reverse order (i.e. bottom to top) whereas a Table cannot.

List items can be aligned using Text::alignment, for more details see ListItem.

List implements Widget and so it can be drawn using Frame::render_widget.

List is also a StatefulWidget, which means you can use it with ListState to allow the user to scroll through items and select one of them.

See the list in the Examples directory for a more in depth example of the various configuration options and for how to handle state.

§Fluent setters

§Examples

use ratatui::{
    layout::Rect,
    style::{Style, Stylize},
    widgets::{Block, List, ListDirection, ListItem},
    Frame,
};

let items = ["Item 1", "Item 2", "Item 3"];
let list = List::new(items)
    .block(Block::bordered().title("List"))
    .style(Style::new().white())
    .highlight_style(Style::new().italic())
    .highlight_symbol(">>")
    .repeat_highlight_symbol(true)
    .direction(ListDirection::BottomToTop);

frame.render_widget(list, area);

§Stateful example

use ratatui::{
    layout::Rect,
    style::{Style, Stylize},
    widgets::{Block, List, ListState},
    Frame,
};

// This should be stored outside of the function in your application state.
let mut state = ListState::default();
let items = ["Item 1", "Item 2", "Item 3"];
let list = List::new(items)
    .block(Block::bordered().title("List"))
    .highlight_style(Style::new().reversed())
    .highlight_symbol(">>")
    .repeat_highlight_symbol(true);

frame.render_stateful_widget(list, area, &mut state);

In addition to List::new, any iterator whose element is convertible to ListItem can be collected into List.

use ratatui::widgets::List;

(0..5).map(|i| format!("Item{i}")).collect::<List>();

Implementations§

Source§

impl<'a> List<'a>

Source

pub fn new<T>(items: T) -> Self
where T: IntoIterator, T::Item: Into<ListItem<'a>>,

Creates a new list from ListItems

The items parameter accepts any value that can be converted into an iterator of Into<ListItem>. This includes arrays of &str or Vecs of Text.

§Example

From a slice of &str

use ratatui::widgets::List;

let list = List::new(["Item 1", "Item 2"]);

From Text

use ratatui::{
    style::{Style, Stylize},
    text::Text,
    widgets::List,
};

let list = List::new([
    Text::styled("Item 1", Style::new().red()),
    Text::styled("Item 2", Style::new().red()),
]);

You can also create an empty list using the Default implementation and use the List::items fluent setter.

use ratatui::widgets::List;

let empty_list = List::default();
let filled_list = empty_list.items(["Item 1"]);
Examples found in repository?
examples/list.rs (line 229)
208    fn render_list(&mut self, area: Rect, buf: &mut Buffer) {
209        let block = Block::new()
210            .title(Line::raw("TODO List").centered())
211            .borders(Borders::TOP)
212            .border_set(symbols::border::EMPTY)
213            .border_style(TODO_HEADER_STYLE)
214            .bg(NORMAL_ROW_BG);
215
216        // Iterate through all elements in the `items` and stylize them.
217        let items: Vec<ListItem> = self
218            .todo_list
219            .items
220            .iter()
221            .enumerate()
222            .map(|(i, todo_item)| {
223                let color = alternate_colors(i);
224                ListItem::from(todo_item).bg(color)
225            })
226            .collect();
227
228        // Create a List from all list items and highlight the currently selected one
229        let list = List::new(items)
230            .block(block)
231            .highlight_style(SELECTED_STYLE)
232            .highlight_symbol(">")
233            .highlight_spacing(HighlightSpacing::Always);
234
235        // We need to disambiguate this trait method as both `Widget` and `StatefulWidget` share the
236        // same method name `render`.
237        StatefulWidget::render(list, area, buf, &mut self.todo_list.state);
238    }
More examples
Hide additional examples
examples/demo2/tabs/email.rs (line 105)
82fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
83    let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
84    let [tabs, inbox] = vertical.areas(area);
85    let theme = THEME.email;
86    Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
87        .style(theme.tabs)
88        .highlight_style(theme.tabs_selected)
89        .select(0)
90        .divider("")
91        .render(tabs, buf);
92
93    let highlight_symbol = ">>";
94    let from_width = EMAILS
95        .iter()
96        .map(|e| e.from.width())
97        .max()
98        .unwrap_or_default();
99    let items = EMAILS.iter().map(|e| {
100        let from = format!("{:width$}", e.from, width = from_width).into();
101        ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
102    });
103    let mut state = ListState::default().with_selected(Some(selected_index));
104    StatefulWidget::render(
105        List::new(items)
106            .style(theme.inbox)
107            .highlight_style(theme.selected_item)
108            .highlight_symbol(highlight_symbol),
109        inbox,
110        buf,
111        &mut state,
112    );
113    let mut scrollbar_state = ScrollbarState::default()
114        .content_length(EMAILS.len())
115        .position(selected_index);
116    Scrollbar::default()
117        .begin_symbol(None)
118        .end_symbol(None)
119        .track_symbol(None)
120        .thumb_symbol("▐")
121        .render(inbox, buf, &mut scrollbar_state);
122}
examples/inline.rs (line 271)
231fn draw(frame: &mut Frame, downloads: &Downloads) {
232    let area = frame.area();
233
234    let block = Block::new().title(Line::from("Progress").centered());
235    frame.render_widget(block, area);
236
237    let vertical = Layout::vertical([Constraint::Length(2), Constraint::Length(4)]).margin(1);
238    let horizontal = Layout::horizontal([Constraint::Percentage(20), Constraint::Percentage(80)]);
239    let [progress_area, main] = vertical.areas(area);
240    let [list_area, gauge_area] = horizontal.areas(main);
241
242    // total progress
243    let done = NUM_DOWNLOADS - downloads.pending.len() - downloads.in_progress.len();
244    #[allow(clippy::cast_precision_loss)]
245    let progress = LineGauge::default()
246        .filled_style(Style::default().fg(Color::Blue))
247        .label(format!("{done}/{NUM_DOWNLOADS}"))
248        .ratio(done as f64 / NUM_DOWNLOADS as f64);
249    frame.render_widget(progress, progress_area);
250
251    // in progress downloads
252    let items: Vec<ListItem> = downloads
253        .in_progress
254        .values()
255        .map(|download| {
256            ListItem::new(Line::from(vec![
257                Span::raw(symbols::DOT),
258                Span::styled(
259                    format!(" download {:>2}", download.id),
260                    Style::default()
261                        .fg(Color::LightGreen)
262                        .add_modifier(Modifier::BOLD),
263                ),
264                Span::raw(format!(
265                    " ({}ms)",
266                    download.started_at.elapsed().as_millis()
267                )),
268            ]))
269        })
270        .collect();
271    let list = List::new(items);
272    frame.render_widget(list, list_area);
273
274    #[allow(clippy::cast_possible_truncation)]
275    for (i, (_, download)) in downloads.in_progress.iter().enumerate() {
276        let gauge = Gauge::default()
277            .gauge_style(Style::default().fg(Color::Yellow))
278            .ratio(download.progress / 100.0);
279        if gauge_area.top().saturating_add(i as u16) > area.bottom() {
280            continue;
281        }
282        frame.render_widget(
283            gauge,
284            Rect {
285                x: gauge_area.left(),
286                y: gauge_area.top().saturating_add(i as u16),
287                width: gauge_area.width,
288                height: 1,
289            },
290        );
291    }
292}
examples/user_input.rs (line 235)
169    fn draw(&self, frame: &mut Frame) {
170        let vertical = Layout::vertical([
171            Constraint::Length(1),
172            Constraint::Length(3),
173            Constraint::Min(1),
174        ]);
175        let [help_area, input_area, messages_area] = vertical.areas(frame.area());
176
177        let (msg, style) = match self.input_mode {
178            InputMode::Normal => (
179                vec![
180                    "Press ".into(),
181                    "q".bold(),
182                    " to exit, ".into(),
183                    "e".bold(),
184                    " to start editing.".bold(),
185                ],
186                Style::default().add_modifier(Modifier::RAPID_BLINK),
187            ),
188            InputMode::Editing => (
189                vec![
190                    "Press ".into(),
191                    "Esc".bold(),
192                    " to stop editing, ".into(),
193                    "Enter".bold(),
194                    " to record the message".into(),
195                ],
196                Style::default(),
197            ),
198        };
199        let text = Text::from(Line::from(msg)).patch_style(style);
200        let help_message = Paragraph::new(text);
201        frame.render_widget(help_message, help_area);
202
203        let input = Paragraph::new(self.input.as_str())
204            .style(match self.input_mode {
205                InputMode::Normal => Style::default(),
206                InputMode::Editing => Style::default().fg(Color::Yellow),
207            })
208            .block(Block::bordered().title("Input"));
209        frame.render_widget(input, input_area);
210        match self.input_mode {
211            // Hide the cursor. `Frame` does this by default, so we don't need to do anything here
212            InputMode::Normal => {}
213
214            // Make the cursor visible and ask ratatui to put it at the specified coordinates after
215            // rendering
216            #[allow(clippy::cast_possible_truncation)]
217            InputMode::Editing => frame.set_cursor_position(Position::new(
218                // Draw the cursor at the current position in the input field.
219                // This position is can be controlled via the left and right arrow key
220                input_area.x + self.character_index as u16 + 1,
221                // Move one line down, from the border to the input line
222                input_area.y + 1,
223            )),
224        }
225
226        let messages: Vec<ListItem> = self
227            .messages
228            .iter()
229            .enumerate()
230            .map(|(i, m)| {
231                let content = Line::from(Span::raw(format!("{i}: {m}")));
232                ListItem::new(content)
233            })
234            .collect();
235        let messages = List::new(messages).block(Block::bordered().title("Messages"));
236        frame.render_widget(messages, messages_area);
237    }
Source

pub fn items<T>(self, items: T) -> Self
where T: IntoIterator, T::Item: Into<ListItem<'a>>,

Set the items

The items parameter accepts any value that can be converted into an iterator of Into<ListItem>. This includes arrays of &str or Vecs of Text.

This is a fluent setter method which must be chained or used as it consumes self.

§Example
use ratatui::widgets::List;

let list = List::default().items(["Item 1", "Item 2"]);
Source

pub fn block(self, block: Block<'a>) -> Self

Wraps the list with a custom Block widget.

The block parameter holds the specified Block to be created around the List

This is a fluent setter method which must be chained or used as it consumes self

§Examples
use ratatui::widgets::{Block, List};

let items = ["Item 1"];
let block = Block::bordered().title("List");
let list = List::new(items).block(block);
Examples found in repository?
examples/list.rs (line 230)
208    fn render_list(&mut self, area: Rect, buf: &mut Buffer) {
209        let block = Block::new()
210            .title(Line::raw("TODO List").centered())
211            .borders(Borders::TOP)
212            .border_set(symbols::border::EMPTY)
213            .border_style(TODO_HEADER_STYLE)
214            .bg(NORMAL_ROW_BG);
215
216        // Iterate through all elements in the `items` and stylize them.
217        let items: Vec<ListItem> = self
218            .todo_list
219            .items
220            .iter()
221            .enumerate()
222            .map(|(i, todo_item)| {
223                let color = alternate_colors(i);
224                ListItem::from(todo_item).bg(color)
225            })
226            .collect();
227
228        // Create a List from all list items and highlight the currently selected one
229        let list = List::new(items)
230            .block(block)
231            .highlight_style(SELECTED_STYLE)
232            .highlight_symbol(">")
233            .highlight_spacing(HighlightSpacing::Always);
234
235        // We need to disambiguate this trait method as both `Widget` and `StatefulWidget` share the
236        // same method name `render`.
237        StatefulWidget::render(list, area, buf, &mut self.todo_list.state);
238    }
More examples
Hide additional examples
examples/user_input.rs (line 235)
169    fn draw(&self, frame: &mut Frame) {
170        let vertical = Layout::vertical([
171            Constraint::Length(1),
172            Constraint::Length(3),
173            Constraint::Min(1),
174        ]);
175        let [help_area, input_area, messages_area] = vertical.areas(frame.area());
176
177        let (msg, style) = match self.input_mode {
178            InputMode::Normal => (
179                vec![
180                    "Press ".into(),
181                    "q".bold(),
182                    " to exit, ".into(),
183                    "e".bold(),
184                    " to start editing.".bold(),
185                ],
186                Style::default().add_modifier(Modifier::RAPID_BLINK),
187            ),
188            InputMode::Editing => (
189                vec![
190                    "Press ".into(),
191                    "Esc".bold(),
192                    " to stop editing, ".into(),
193                    "Enter".bold(),
194                    " to record the message".into(),
195                ],
196                Style::default(),
197            ),
198        };
199        let text = Text::from(Line::from(msg)).patch_style(style);
200        let help_message = Paragraph::new(text);
201        frame.render_widget(help_message, help_area);
202
203        let input = Paragraph::new(self.input.as_str())
204            .style(match self.input_mode {
205                InputMode::Normal => Style::default(),
206                InputMode::Editing => Style::default().fg(Color::Yellow),
207            })
208            .block(Block::bordered().title("Input"));
209        frame.render_widget(input, input_area);
210        match self.input_mode {
211            // Hide the cursor. `Frame` does this by default, so we don't need to do anything here
212            InputMode::Normal => {}
213
214            // Make the cursor visible and ask ratatui to put it at the specified coordinates after
215            // rendering
216            #[allow(clippy::cast_possible_truncation)]
217            InputMode::Editing => frame.set_cursor_position(Position::new(
218                // Draw the cursor at the current position in the input field.
219                // This position is can be controlled via the left and right arrow key
220                input_area.x + self.character_index as u16 + 1,
221                // Move one line down, from the border to the input line
222                input_area.y + 1,
223            )),
224        }
225
226        let messages: Vec<ListItem> = self
227            .messages
228            .iter()
229            .enumerate()
230            .map(|(i, m)| {
231                let content = Line::from(Span::raw(format!("{i}: {m}")));
232                ListItem::new(content)
233            })
234            .collect();
235        let messages = List::new(messages).block(Block::bordered().title("Messages"));
236        frame.render_widget(messages, messages_area);
237    }
Source

pub fn style<S: Into<Style>>(self, style: S) -> Self

Sets the base style of the widget

style accepts any type that is convertible to Style (e.g. Style, Color, or your own type that implements Into<Style>).

All text rendered by the widget will use this style, unless overridden by Block::style, ListItem::style, or the styles of the ListItem’s content.

This is a fluent setter method which must be chained or used as it consumes self

§Examples
use ratatui::{
    style::{Style, Stylize},
    widgets::List,
};

let items = ["Item 1"];
let list = List::new(items).style(Style::new().red().italic());

List also implements the Styled trait, which means you can use style shorthands from the Stylize trait to set the style of the widget more concisely.

use ratatui::{style::Stylize, widgets::List};

let items = ["Item 1"];
let list = List::new(items).red().italic();
Examples found in repository?
examples/demo2/tabs/email.rs (line 106)
82fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
83    let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
84    let [tabs, inbox] = vertical.areas(area);
85    let theme = THEME.email;
86    Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
87        .style(theme.tabs)
88        .highlight_style(theme.tabs_selected)
89        .select(0)
90        .divider("")
91        .render(tabs, buf);
92
93    let highlight_symbol = ">>";
94    let from_width = EMAILS
95        .iter()
96        .map(|e| e.from.width())
97        .max()
98        .unwrap_or_default();
99    let items = EMAILS.iter().map(|e| {
100        let from = format!("{:width$}", e.from, width = from_width).into();
101        ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
102    });
103    let mut state = ListState::default().with_selected(Some(selected_index));
104    StatefulWidget::render(
105        List::new(items)
106            .style(theme.inbox)
107            .highlight_style(theme.selected_item)
108            .highlight_symbol(highlight_symbol),
109        inbox,
110        buf,
111        &mut state,
112    );
113    let mut scrollbar_state = ScrollbarState::default()
114        .content_length(EMAILS.len())
115        .position(selected_index);
116    Scrollbar::default()
117        .begin_symbol(None)
118        .end_symbol(None)
119        .track_symbol(None)
120        .thumb_symbol("▐")
121        .render(inbox, buf, &mut scrollbar_state);
122}
Source

pub const fn highlight_symbol(self, highlight_symbol: &'a str) -> Self

Set the symbol to be displayed in front of the selected item

By default there are no highlight symbol.

This is a fluent setter method which must be chained or used as it consumes self

§Examples
use ratatui::widgets::List;

let items = ["Item 1", "Item 2"];
let list = List::new(items).highlight_symbol(">>");
Examples found in repository?
examples/list.rs (line 232)
208    fn render_list(&mut self, area: Rect, buf: &mut Buffer) {
209        let block = Block::new()
210            .title(Line::raw("TODO List").centered())
211            .borders(Borders::TOP)
212            .border_set(symbols::border::EMPTY)
213            .border_style(TODO_HEADER_STYLE)
214            .bg(NORMAL_ROW_BG);
215
216        // Iterate through all elements in the `items` and stylize them.
217        let items: Vec<ListItem> = self
218            .todo_list
219            .items
220            .iter()
221            .enumerate()
222            .map(|(i, todo_item)| {
223                let color = alternate_colors(i);
224                ListItem::from(todo_item).bg(color)
225            })
226            .collect();
227
228        // Create a List from all list items and highlight the currently selected one
229        let list = List::new(items)
230            .block(block)
231            .highlight_style(SELECTED_STYLE)
232            .highlight_symbol(">")
233            .highlight_spacing(HighlightSpacing::Always);
234
235        // We need to disambiguate this trait method as both `Widget` and `StatefulWidget` share the
236        // same method name `render`.
237        StatefulWidget::render(list, area, buf, &mut self.todo_list.state);
238    }
More examples
Hide additional examples
examples/demo2/tabs/email.rs (line 108)
82fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
83    let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
84    let [tabs, inbox] = vertical.areas(area);
85    let theme = THEME.email;
86    Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
87        .style(theme.tabs)
88        .highlight_style(theme.tabs_selected)
89        .select(0)
90        .divider("")
91        .render(tabs, buf);
92
93    let highlight_symbol = ">>";
94    let from_width = EMAILS
95        .iter()
96        .map(|e| e.from.width())
97        .max()
98        .unwrap_or_default();
99    let items = EMAILS.iter().map(|e| {
100        let from = format!("{:width$}", e.from, width = from_width).into();
101        ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
102    });
103    let mut state = ListState::default().with_selected(Some(selected_index));
104    StatefulWidget::render(
105        List::new(items)
106            .style(theme.inbox)
107            .highlight_style(theme.selected_item)
108            .highlight_symbol(highlight_symbol),
109        inbox,
110        buf,
111        &mut state,
112    );
113    let mut scrollbar_state = ScrollbarState::default()
114        .content_length(EMAILS.len())
115        .position(selected_index);
116    Scrollbar::default()
117        .begin_symbol(None)
118        .end_symbol(None)
119        .track_symbol(None)
120        .thumb_symbol("▐")
121        .render(inbox, buf, &mut scrollbar_state);
122}
Source

pub fn highlight_style<S: Into<Style>>(self, style: S) -> Self

Set the style of the selected item

style accepts any type that is convertible to Style (e.g. Style, Color, or your own type that implements Into<Style>).

This style will be applied to the entire item, including the highlight symbol if it is displayed, and will override any style set on the item or on the individual cells.

This is a fluent setter method which must be chained or used as it consumes self

§Examples
use ratatui::{
    style::{Style, Stylize},
    widgets::List,
};

let items = ["Item 1", "Item 2"];
let list = List::new(items).highlight_style(Style::new().red().italic());
Examples found in repository?
examples/list.rs (line 231)
208    fn render_list(&mut self, area: Rect, buf: &mut Buffer) {
209        let block = Block::new()
210            .title(Line::raw("TODO List").centered())
211            .borders(Borders::TOP)
212            .border_set(symbols::border::EMPTY)
213            .border_style(TODO_HEADER_STYLE)
214            .bg(NORMAL_ROW_BG);
215
216        // Iterate through all elements in the `items` and stylize them.
217        let items: Vec<ListItem> = self
218            .todo_list
219            .items
220            .iter()
221            .enumerate()
222            .map(|(i, todo_item)| {
223                let color = alternate_colors(i);
224                ListItem::from(todo_item).bg(color)
225            })
226            .collect();
227
228        // Create a List from all list items and highlight the currently selected one
229        let list = List::new(items)
230            .block(block)
231            .highlight_style(SELECTED_STYLE)
232            .highlight_symbol(">")
233            .highlight_spacing(HighlightSpacing::Always);
234
235        // We need to disambiguate this trait method as both `Widget` and `StatefulWidget` share the
236        // same method name `render`.
237        StatefulWidget::render(list, area, buf, &mut self.todo_list.state);
238    }
More examples
Hide additional examples
examples/demo2/tabs/email.rs (line 107)
82fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
83    let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
84    let [tabs, inbox] = vertical.areas(area);
85    let theme = THEME.email;
86    Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
87        .style(theme.tabs)
88        .highlight_style(theme.tabs_selected)
89        .select(0)
90        .divider("")
91        .render(tabs, buf);
92
93    let highlight_symbol = ">>";
94    let from_width = EMAILS
95        .iter()
96        .map(|e| e.from.width())
97        .max()
98        .unwrap_or_default();
99    let items = EMAILS.iter().map(|e| {
100        let from = format!("{:width$}", e.from, width = from_width).into();
101        ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
102    });
103    let mut state = ListState::default().with_selected(Some(selected_index));
104    StatefulWidget::render(
105        List::new(items)
106            .style(theme.inbox)
107            .highlight_style(theme.selected_item)
108            .highlight_symbol(highlight_symbol),
109        inbox,
110        buf,
111        &mut state,
112    );
113    let mut scrollbar_state = ScrollbarState::default()
114        .content_length(EMAILS.len())
115        .position(selected_index);
116    Scrollbar::default()
117        .begin_symbol(None)
118        .end_symbol(None)
119        .track_symbol(None)
120        .thumb_symbol("▐")
121        .render(inbox, buf, &mut scrollbar_state);
122}
Source

pub const fn repeat_highlight_symbol(self, repeat: bool) -> Self

Set whether to repeat the highlight symbol and style over selected multi-line items

This is false by default.

This is a fluent setter method which must be chained or used as it consumes self

Source

pub const fn highlight_spacing(self, value: HighlightSpacing) -> Self

Set when to show the highlight spacing

The highlight spacing is the spacing that is allocated for the selection symbol (if enabled) and is used to shift the list when an item is selected. This method allows you to configure when this spacing is allocated.

  • HighlightSpacing::Always will always allocate the spacing, regardless of whether an item is selected or not. This means that the table will never change size, regardless of if an item is selected or not.
  • HighlightSpacing::WhenSelected will only allocate the spacing if an item is selected. This means that the table will shift when an item is selected. This is the default setting for backwards compatibility, but it is recommended to use HighlightSpacing::Always for a better user experience.
  • HighlightSpacing::Never will never allocate the spacing, regardless of whether an item is selected or not. This means that the highlight symbol will never be drawn.

This is a fluent setter method which must be chained or used as it consumes self

§Examples
use ratatui::widgets::{HighlightSpacing, List};

let items = ["Item 1"];
let list = List::new(items).highlight_spacing(HighlightSpacing::Always);
Examples found in repository?
examples/list.rs (line 233)
208    fn render_list(&mut self, area: Rect, buf: &mut Buffer) {
209        let block = Block::new()
210            .title(Line::raw("TODO List").centered())
211            .borders(Borders::TOP)
212            .border_set(symbols::border::EMPTY)
213            .border_style(TODO_HEADER_STYLE)
214            .bg(NORMAL_ROW_BG);
215
216        // Iterate through all elements in the `items` and stylize them.
217        let items: Vec<ListItem> = self
218            .todo_list
219            .items
220            .iter()
221            .enumerate()
222            .map(|(i, todo_item)| {
223                let color = alternate_colors(i);
224                ListItem::from(todo_item).bg(color)
225            })
226            .collect();
227
228        // Create a List from all list items and highlight the currently selected one
229        let list = List::new(items)
230            .block(block)
231            .highlight_style(SELECTED_STYLE)
232            .highlight_symbol(">")
233            .highlight_spacing(HighlightSpacing::Always);
234
235        // We need to disambiguate this trait method as both `Widget` and `StatefulWidget` share the
236        // same method name `render`.
237        StatefulWidget::render(list, area, buf, &mut self.todo_list.state);
238    }
Source

pub const fn direction(self, direction: ListDirection) -> Self

Defines the list direction (up or down)

Defines if the List is displayed top to bottom (default) or bottom to top. If there is too few items to fill the screen, the list will stick to the starting edge.

This is a fluent setter method which must be chained or used as it consumes self

§Example

Bottom to top

use ratatui::widgets::{List, ListDirection};

let items = ["Item 1"];
let list = List::new(items).direction(ListDirection::BottomToTop);
Source

pub const fn scroll_padding(self, padding: usize) -> Self

Sets the number of items around the currently selected item that should be kept visible

This is a fluent setter method which must be chained or used as it consumes self

§Example

A padding value of 1 will keep 1 item above and 1 item bellow visible if possible

use ratatui::widgets::List;

let items = ["Item 1"];
let list = List::new(items).scroll_padding(1);
Source

pub fn len(&self) -> usize

Returns the number of ListItems in the list

Source

pub fn is_empty(&self) -> bool

Returns true if the list contains no elements.

Trait Implementations§

Source§

impl<'a> Clone for List<'a>

Source§

fn clone(&self) -> List<'a>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for List<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Default for List<'a>

Source§

fn default() -> List<'a>

Returns the “default value” for a type. Read more
Source§

impl<'a, Item> FromIterator<Item> for List<'a>
where Item: Into<ListItem<'a>>,

Source§

fn from_iter<Iter: IntoIterator<Item = Item>>(iter: Iter) -> Self

Creates a value from an iterator. Read more
Source§

impl<'a> Hash for List<'a>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<'a> PartialEq for List<'a>

Source§

fn eq(&self, other: &List<'a>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StatefulWidget for &List<'_>

Source§

type State = ListState

State associated with the stateful widget. Read more
Source§

fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)

Draws the current state of the widget in the given buffer. That is the only method required to implement a custom stateful widget.
Source§

impl StatefulWidget for List<'_>

Source§

type State = ListState

State associated with the stateful widget. Read more
Source§

fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State)

Draws the current state of the widget in the given buffer. That is the only method required to implement a custom stateful widget.
Source§

impl StatefulWidgetRef for List<'_>

Source§

type State = ListState

Available on crate feature unstable-widget-ref only.
State associated with the stateful widget. Read more
Source§

fn render_ref(&self, area: Rect, buf: &mut Buffer, state: &mut Self::State)

Available on crate feature unstable-widget-ref only.
Draws the current state of the widget in the given buffer. That is the only method required to implement a custom stateful widget.
Source§

impl<'a> Styled for List<'a>

Source§

type Item = List<'a>

Source§

fn style(&self) -> Style

Returns the style of the object.
Source§

fn set_style<S: Into<Style>>(self, style: S) -> Self::Item

Sets the style of the object. Read more
Source§

impl Widget for List<'_>

Source§

fn render(self, area: Rect, buf: &mut Buffer)

Draws the current state of the widget in the given buffer. That is the only method required to implement a custom widget.
Source§

impl WidgetRef for List<'_>

Source§

fn render_ref(&self, area: Rect, buf: &mut Buffer)

Available on crate feature unstable-widget-ref only.
Draws the current state of the widget in the given buffer. That is the only method required to implement a custom widget.
Source§

impl<'a> Eq for List<'a>

Source§

impl<'a> StructuralPartialEq for List<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for List<'a>

§

impl<'a> RefUnwindSafe for List<'a>

§

impl<'a> Send for List<'a>

§

impl<'a> Sync for List<'a>

§

impl<'a> Unpin for List<'a>

§

impl<'a> UnwindSafe for List<'a>

Blanket Implementations§

Source§

impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
where T: Real + Zero + Arithmetics + Clone, Swp: WhitePoint<T>, Dwp: WhitePoint<T>, D: AdaptFrom<S, Swp, Dwp, T>,

Source§

fn adapt_into_using<M>(self, method: M) -> D
where M: TransformMatrix<T>,

Convert the source color to the destination color using the specified method.
Source§

fn adapt_into(self) -> D

Convert the source color to the destination color using the bradford method by default.
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, C> ArraysFrom<C> for T
where C: IntoArrays<T>,

Source§

fn arrays_from(colors: C) -> T

Cast a collection of colors into a collection of arrays.
Source§

impl<T, C> ArraysInto<C> for T
where C: FromArrays<T>,

Source§

fn arrays_into(self) -> C

Cast this collection of arrays into a collection of colors.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for U
where T: FromCam16Unclamped<WpParam, U>,

Source§

type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T, C> ComponentsFrom<C> for T
where C: IntoComponents<T>,

Source§

fn components_from(colors: C) -> T

Cast a collection of colors into a collection of color components.
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromAngle<T> for T

Source§

fn from_angle(angle: T) -> T

Performs a conversion from angle.
Source§

impl<T, U> FromStimulus<U> for T
where U: IntoStimulus<T>,

Source§

fn from_stimulus(other: U) -> T

Converts other into Self, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> IntoAngle<U> for T
where U: FromAngle<T>,

Source§

fn into_angle(self) -> U

Performs a conversion into T.
Source§

impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for U
where T: Cam16FromUnclamped<WpParam, U>,

Source§

type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, U> IntoColor<U> for T
where U: FromColor<T>,

Source§

fn into_color(self) -> U

Convert into T with values clamped to the color defined bounds Read more
Source§

impl<T, U> IntoColorUnclamped<U> for T
where U: FromColorUnclamped<T>,

Source§

fn into_color_unclamped(self) -> U

Convert into T. The resulting color might be invalid in its color space Read more
Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoStimulus<T> for T

Source§

fn into_stimulus(self) -> T

Converts self into T, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<'a, T, U> Stylize<'a, T> for U
where U: Styled<Item = T>,

Source§

fn bg<C>(self, color: C) -> T
where C: Into<Color>,

Source§

fn fg<C>(self, color: C) -> T
where C: Into<Color>,

Source§

fn add_modifier(self, modifier: Modifier) -> T

Source§

fn remove_modifier(self, modifier: Modifier) -> T

Source§

fn reset(self) -> T

Source§

fn black(self) -> T

Sets the foreground color to black.
Source§

fn on_black(self) -> T

Sets the background color to black.
Source§

fn red(self) -> T

Sets the foreground color to red.
Source§

fn on_red(self) -> T

Sets the background color to red.
Source§

fn green(self) -> T

Sets the foreground color to green.
Source§

fn on_green(self) -> T

Sets the background color to green.
Source§

fn yellow(self) -> T

Sets the foreground color to yellow.
Source§

fn on_yellow(self) -> T

Sets the background color to yellow.
Source§

fn blue(self) -> T

Sets the foreground color to blue.
Source§

fn on_blue(self) -> T

Sets the background color to blue.
Source§

fn magenta(self) -> T

Sets the foreground color to magenta.
Source§

fn on_magenta(self) -> T

Sets the background color to magenta.
Source§

fn cyan(self) -> T

Sets the foreground color to cyan.
Source§

fn on_cyan(self) -> T

Sets the background color to cyan.
Source§

fn gray(self) -> T

Sets the foreground color to gray.
Source§

fn on_gray(self) -> T

Sets the background color to gray.
Source§

fn dark_gray(self) -> T

Sets the foreground color to dark_gray.
Source§

fn on_dark_gray(self) -> T

Sets the background color to dark_gray.
Source§

fn light_red(self) -> T

Sets the foreground color to light_red.
Source§

fn on_light_red(self) -> T

Sets the background color to light_red.
Source§

fn light_green(self) -> T

Sets the foreground color to light_green.
Source§

fn on_light_green(self) -> T

Sets the background color to light_green.
Source§

fn light_yellow(self) -> T

Sets the foreground color to light_yellow.
Source§

fn on_light_yellow(self) -> T

Sets the background color to light_yellow.
Source§

fn light_blue(self) -> T

Sets the foreground color to light_blue.
Source§

fn on_light_blue(self) -> T

Sets the background color to light_blue.
Source§

fn light_magenta(self) -> T

Sets the foreground color to light_magenta.
Source§

fn on_light_magenta(self) -> T

Sets the background color to light_magenta.
Source§

fn light_cyan(self) -> T

Sets the foreground color to light_cyan.
Source§

fn on_light_cyan(self) -> T

Sets the background color to light_cyan.
Source§

fn white(self) -> T

Sets the foreground color to white.
Source§

fn on_white(self) -> T

Sets the background color to white.
Source§

fn bold(self) -> T

Adds the BOLD modifier.
Source§

fn not_bold(self) -> T

Removes the BOLD modifier.
Source§

fn dim(self) -> T

Adds the DIM modifier.
Source§

fn not_dim(self) -> T

Removes the DIM modifier.
Source§

fn italic(self) -> T

Adds the ITALIC modifier.
Source§

fn not_italic(self) -> T

Removes the ITALIC modifier.
Source§

fn underlined(self) -> T

Adds the UNDERLINED modifier.
Source§

fn not_underlined(self) -> T

Removes the UNDERLINED modifier.
Adds the SLOW_BLINK modifier.
Removes the SLOW_BLINK modifier.
Adds the RAPID_BLINK modifier.
Removes the RAPID_BLINK modifier.
Source§

fn reversed(self) -> T

Adds the REVERSED modifier.
Source§

fn not_reversed(self) -> T

Removes the REVERSED modifier.
Source§

fn hidden(self) -> T

Adds the HIDDEN modifier.
Source§

fn not_hidden(self) -> T

Removes the HIDDEN modifier.
Source§

fn crossed_out(self) -> T

Adds the CROSSED_OUT modifier.
Source§

fn not_crossed_out(self) -> T

Removes the CROSSED_OUT modifier.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, C> TryComponentsInto<C> for T
where C: TryFromComponents<T>,

Source§

type Error = <C as TryFromComponents<T>>::Error

The error for when try_into_colors fails to cast.
Source§

fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>

Try to cast this collection of color components into a collection of colors. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T, U> TryIntoColor<U> for T
where U: TryFromColor<T>,

Source§

fn try_into_color(self) -> Result<U, OutOfBounds<U>>

Convert into T, returning ok if the color is inside of its defined range, otherwise an OutOfBounds error is returned which contains the unclamped color. Read more
Source§

impl<C, U> UintsFrom<C> for U
where C: IntoUints<U>,

Source§

fn uints_from(colors: C) -> U

Cast a collection of colors into a collection of unsigned integers.
Source§

impl<C, U> UintsInto<C> for U
where C: FromUints<U>,

Source§

fn uints_into(self) -> C

Cast this collection of unsigned integers into a collection of colors.