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 ListItem
s.
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
List::highlight_style
sets the style of the selected item.List::highlight_symbol
sets the symbol to be displayed in front of the selected item.List::repeat_highlight_symbol
sets whether to repeat the symbol and style over selected multi-line itemsList::direction
sets the list direction
§Examples
use ratatui::{prelude::*, widgets::*};
let items = ["Item 1", "Item 2", "Item 3"];
let list = List::new(items)
.block(Block::bordered().title("List"))
.style(Style::default().fg(Color::White))
.highlight_style(Style::default().add_modifier(Modifier::ITALIC))
.highlight_symbol(">>")
.repeat_highlight_symbol(true)
.direction(ListDirection::BottomToTop);
frame.render_widget(list, area);
§Stateful example
// 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().add_modifier(Modifier::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>
impl<'a> List<'a>
sourcepub fn new<T>(items: T) -> Self
pub fn new<T>(items: T) -> Self
Creates a new list from ListItem
s
The items
parameter accepts any value that can be converted into an iterator of
Into<ListItem>
. This includes arrays of &str
or Vec
s of Text
.
§Example
From a slice of &str
let list = List::new(["Item 1", "Item 2"]);
From Text
let list = List::new([
Text::styled("Item 1", Style::default().red()),
Text::styled("Item 2", Style::default().red()),
]);
You can also create an empty list using the Default
implementation and use the
List::items
fluent setter.
let empty_list = List::default();
let filled_list = empty_list.items(["Item 1"]);
Examples found in repository?
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
let [tabs, inbox] = vertical.areas(area);
let theme = THEME.email;
Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
.style(theme.tabs)
.highlight_style(theme.tabs_selected)
.select(0)
.divider("")
.render(tabs, buf);
let highlight_symbol = ">>";
let from_width = EMAILS
.iter()
.map(|e| e.from.width())
.max()
.unwrap_or_default();
let items = EMAILS
.iter()
.map(|e| {
let from = format!("{:width$}", e.from, width = from_width).into();
ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
})
.collect_vec();
let mut state = ListState::default().with_selected(Some(selected_index));
StatefulWidget::render(
List::new(items)
.style(theme.inbox)
.highlight_style(theme.selected_item)
.highlight_symbol(highlight_symbol),
inbox,
buf,
&mut state,
);
let mut scrollbar_state = ScrollbarState::default()
.content_length(EMAILS.len())
.position(selected_index);
Scrollbar::default()
.begin_symbol(None)
.end_symbol(None)
.track_symbol(None)
.thumb_symbol("▐")
.render(inbox, buf, &mut scrollbar_state);
}
More examples
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
fn render_todo(&mut self, area: Rect, buf: &mut Buffer) {
// We create two blocks, one is for the header (outer) and the other is for list (inner).
let outer_block = Block::new()
.borders(Borders::NONE)
.title_alignment(Alignment::Center)
.title("TODO List")
.fg(TEXT_COLOR)
.bg(TODO_HEADER_BG);
let inner_block = Block::new()
.borders(Borders::NONE)
.fg(TEXT_COLOR)
.bg(NORMAL_ROW_COLOR);
// We get the inner area from outer_block. We'll use this area later to render the table.
let outer_area = area;
let inner_area = outer_block.inner(outer_area);
// We can render the header in outer_area.
outer_block.render(outer_area, buf);
// Iterate through all elements in the `items` and stylize them.
let items: Vec<ListItem> = self
.items
.items
.iter()
.enumerate()
.map(|(i, todo_item)| todo_item.to_list_item(i))
.collect();
// Create a List from all list items and highlight the currently selected one
let items = List::new(items)
.block(inner_block)
.highlight_style(
Style::default()
.add_modifier(Modifier::BOLD)
.add_modifier(Modifier::REVERSED)
.fg(SELECTED_STYLE_FG),
)
.highlight_symbol(">")
.highlight_spacing(HighlightSpacing::Always);
// We can now render the item list
// (look careful we are using StatefulWidget's render.)
// ratatui::widgets::StatefulWidget::render as stateful_render
StatefulWidget::render(items, inner_area, buf, &mut self.items.state);
}
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
fn ui(f: &mut Frame, downloads: &Downloads) {
let area = f.size();
let block = Block::new().title(block::Title::from("Progress").alignment(Alignment::Center));
f.render_widget(block, area);
let vertical = Layout::vertical([Constraint::Length(2), Constraint::Length(4)]).margin(1);
let horizontal = Layout::horizontal([Constraint::Percentage(20), Constraint::Percentage(80)]);
let [progress_area, main] = vertical.areas(area);
let [list_area, gauge_area] = horizontal.areas(main);
// total progress
let done = NUM_DOWNLOADS - downloads.pending.len() - downloads.in_progress.len();
#[allow(clippy::cast_precision_loss)]
let progress = LineGauge::default()
.gauge_style(Style::default().fg(Color::Blue))
.label(format!("{done}/{NUM_DOWNLOADS}"))
.ratio(done as f64 / NUM_DOWNLOADS as f64);
f.render_widget(progress, progress_area);
// in progress downloads
let items: Vec<ListItem> = downloads
.in_progress
.values()
.map(|download| {
ListItem::new(Line::from(vec![
Span::raw(symbols::DOT),
Span::styled(
format!(" download {:>2}", download.id),
Style::default()
.fg(Color::LightGreen)
.add_modifier(Modifier::BOLD),
),
Span::raw(format!(
" ({}ms)",
download.started_at.elapsed().as_millis()
)),
]))
})
.collect();
let list = List::new(items);
f.render_widget(list, list_area);
#[allow(clippy::cast_possible_truncation)]
for (i, (_, download)) in downloads.in_progress.iter().enumerate() {
let gauge = Gauge::default()
.gauge_style(Style::default().fg(Color::Yellow))
.ratio(download.progress / 100.0);
if gauge_area.top().saturating_add(i as u16) > area.bottom() {
continue;
}
f.render_widget(
gauge,
Rect {
x: gauge_area.left(),
y: gauge_area.top().saturating_add(i as u16),
width: gauge_area.width,
height: 1,
},
);
}
}
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
fn ui(f: &mut Frame, app: &App) {
let vertical = Layout::vertical([
Constraint::Length(1),
Constraint::Length(3),
Constraint::Min(1),
]);
let [help_area, input_area, messages_area] = vertical.areas(f.size());
let (msg, style) = match app.input_mode {
InputMode::Normal => (
vec![
"Press ".into(),
"q".bold(),
" to exit, ".into(),
"e".bold(),
" to start editing.".bold(),
],
Style::default().add_modifier(Modifier::RAPID_BLINK),
),
InputMode::Editing => (
vec![
"Press ".into(),
"Esc".bold(),
" to stop editing, ".into(),
"Enter".bold(),
" to record the message".into(),
],
Style::default(),
),
};
let text = Text::from(Line::from(msg)).patch_style(style);
let help_message = Paragraph::new(text);
f.render_widget(help_message, help_area);
let input = Paragraph::new(app.input.as_str())
.style(match app.input_mode {
InputMode::Normal => Style::default(),
InputMode::Editing => Style::default().fg(Color::Yellow),
})
.block(Block::bordered().title("Input"));
f.render_widget(input, input_area);
match app.input_mode {
InputMode::Normal =>
// Hide the cursor. `Frame` does this by default, so we don't need to do anything here
{}
InputMode::Editing => {
// Make the cursor visible and ask ratatui to put it at the specified coordinates after
// rendering
#[allow(clippy::cast_possible_truncation)]
f.set_cursor(
// Draw the cursor at the current position in the input field.
// This position is can be controlled via the left and right arrow key
input_area.x + app.character_index as u16 + 1,
// Move one line down, from the border to the input line
input_area.y + 1,
);
}
}
let messages: Vec<ListItem> = app
.messages
.iter()
.enumerate()
.map(|(i, m)| {
let content = Line::from(Span::raw(format!("{i}: {m}")));
ListItem::new(content)
})
.collect();
let messages = List::new(messages).block(Block::bordered().title("Messages"));
f.render_widget(messages, messages_area);
}
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
fn draw_charts(f: &mut Frame, app: &mut App, area: Rect) {
let constraints = if app.show_chart {
vec![Constraint::Percentage(50), Constraint::Percentage(50)]
} else {
vec![Constraint::Percentage(100)]
};
let chunks = Layout::horizontal(constraints).split(area);
{
let chunks = Layout::vertical([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[0]);
{
let chunks =
Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[0]);
// Draw tasks
let tasks: Vec<ListItem> = app
.tasks
.items
.iter()
.map(|i| ListItem::new(vec![text::Line::from(Span::raw(*i))]))
.collect();
let tasks = List::new(tasks)
.block(Block::bordered().title("List"))
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
.highlight_symbol("> ");
f.render_stateful_widget(tasks, chunks[0], &mut app.tasks.state);
// Draw logs
let info_style = Style::default().fg(Color::Blue);
let warning_style = Style::default().fg(Color::Yellow);
let error_style = Style::default().fg(Color::Magenta);
let critical_style = Style::default().fg(Color::Red);
let logs: Vec<ListItem> = app
.logs
.items
.iter()
.map(|&(evt, level)| {
let s = match level {
"ERROR" => error_style,
"CRITICAL" => critical_style,
"WARNING" => warning_style,
_ => info_style,
};
let content = vec![text::Line::from(vec![
Span::styled(format!("{level:<9}"), s),
Span::raw(evt),
])];
ListItem::new(content)
})
.collect();
let logs = List::new(logs).block(Block::bordered().title("List"));
f.render_stateful_widget(logs, chunks[1], &mut app.logs.state);
}
let barchart = BarChart::default()
.block(Block::bordered().title("Bar chart"))
.data(&app.barchart)
.bar_width(3)
.bar_gap(2)
.bar_set(if app.enhanced_graphics {
symbols::bar::NINE_LEVELS
} else {
symbols::bar::THREE_LEVELS
})
.value_style(
Style::default()
.fg(Color::Black)
.bg(Color::Green)
.add_modifier(Modifier::ITALIC),
)
.label_style(Style::default().fg(Color::Yellow))
.bar_style(Style::default().fg(Color::Green));
f.render_widget(barchart, chunks[1]);
}
if app.show_chart {
let x_labels = vec![
Span::styled(
format!("{}", app.signals.window[0]),
Style::default().add_modifier(Modifier::BOLD),
),
Span::raw(format!(
"{}",
(app.signals.window[0] + app.signals.window[1]) / 2.0
)),
Span::styled(
format!("{}", app.signals.window[1]),
Style::default().add_modifier(Modifier::BOLD),
),
];
let datasets = vec![
Dataset::default()
.name("data2")
.marker(symbols::Marker::Dot)
.style(Style::default().fg(Color::Cyan))
.data(&app.signals.sin1.points),
Dataset::default()
.name("data3")
.marker(if app.enhanced_graphics {
symbols::Marker::Braille
} else {
symbols::Marker::Dot
})
.style(Style::default().fg(Color::Yellow))
.data(&app.signals.sin2.points),
];
let chart = Chart::new(datasets)
.block(
Block::bordered().title(Span::styled(
"Chart",
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
)),
)
.x_axis(
Axis::default()
.title("X Axis")
.style(Style::default().fg(Color::Gray))
.bounds(app.signals.window)
.labels(x_labels),
)
.y_axis(
Axis::default()
.title("Y Axis")
.style(Style::default().fg(Color::Gray))
.bounds([-20.0, 20.0])
.labels(vec![
Span::styled("-20", Style::default().add_modifier(Modifier::BOLD)),
Span::raw("0"),
Span::styled("20", Style::default().add_modifier(Modifier::BOLD)),
]),
);
f.render_widget(chart, chunks[1]);
}
}
sourcepub fn items<T>(self, items: T) -> Self
pub fn items<T>(self, items: T) -> Self
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 Vec
s of Text
.
This is a fluent setter method which must be chained or used as it consumes self.
§Example
let list = List::default().items(["Item 1", "Item 2"]);
sourcepub fn block(self, block: Block<'a>) -> Self
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
let block = Block::bordered().title("List");
let list = List::new(items).block(block);
Examples found in repository?
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
fn render_todo(&mut self, area: Rect, buf: &mut Buffer) {
// We create two blocks, one is for the header (outer) and the other is for list (inner).
let outer_block = Block::new()
.borders(Borders::NONE)
.title_alignment(Alignment::Center)
.title("TODO List")
.fg(TEXT_COLOR)
.bg(TODO_HEADER_BG);
let inner_block = Block::new()
.borders(Borders::NONE)
.fg(TEXT_COLOR)
.bg(NORMAL_ROW_COLOR);
// We get the inner area from outer_block. We'll use this area later to render the table.
let outer_area = area;
let inner_area = outer_block.inner(outer_area);
// We can render the header in outer_area.
outer_block.render(outer_area, buf);
// Iterate through all elements in the `items` and stylize them.
let items: Vec<ListItem> = self
.items
.items
.iter()
.enumerate()
.map(|(i, todo_item)| todo_item.to_list_item(i))
.collect();
// Create a List from all list items and highlight the currently selected one
let items = List::new(items)
.block(inner_block)
.highlight_style(
Style::default()
.add_modifier(Modifier::BOLD)
.add_modifier(Modifier::REVERSED)
.fg(SELECTED_STYLE_FG),
)
.highlight_symbol(">")
.highlight_spacing(HighlightSpacing::Always);
// We can now render the item list
// (look careful we are using StatefulWidget's render.)
// ratatui::widgets::StatefulWidget::render as stateful_render
StatefulWidget::render(items, inner_area, buf, &mut self.items.state);
}
More examples
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
fn ui(f: &mut Frame, app: &App) {
let vertical = Layout::vertical([
Constraint::Length(1),
Constraint::Length(3),
Constraint::Min(1),
]);
let [help_area, input_area, messages_area] = vertical.areas(f.size());
let (msg, style) = match app.input_mode {
InputMode::Normal => (
vec![
"Press ".into(),
"q".bold(),
" to exit, ".into(),
"e".bold(),
" to start editing.".bold(),
],
Style::default().add_modifier(Modifier::RAPID_BLINK),
),
InputMode::Editing => (
vec![
"Press ".into(),
"Esc".bold(),
" to stop editing, ".into(),
"Enter".bold(),
" to record the message".into(),
],
Style::default(),
),
};
let text = Text::from(Line::from(msg)).patch_style(style);
let help_message = Paragraph::new(text);
f.render_widget(help_message, help_area);
let input = Paragraph::new(app.input.as_str())
.style(match app.input_mode {
InputMode::Normal => Style::default(),
InputMode::Editing => Style::default().fg(Color::Yellow),
})
.block(Block::bordered().title("Input"));
f.render_widget(input, input_area);
match app.input_mode {
InputMode::Normal =>
// Hide the cursor. `Frame` does this by default, so we don't need to do anything here
{}
InputMode::Editing => {
// Make the cursor visible and ask ratatui to put it at the specified coordinates after
// rendering
#[allow(clippy::cast_possible_truncation)]
f.set_cursor(
// Draw the cursor at the current position in the input field.
// This position is can be controlled via the left and right arrow key
input_area.x + app.character_index as u16 + 1,
// Move one line down, from the border to the input line
input_area.y + 1,
);
}
}
let messages: Vec<ListItem> = app
.messages
.iter()
.enumerate()
.map(|(i, m)| {
let content = Line::from(Span::raw(format!("{i}: {m}")));
ListItem::new(content)
})
.collect();
let messages = List::new(messages).block(Block::bordered().title("Messages"));
f.render_widget(messages, messages_area);
}
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
fn draw_charts(f: &mut Frame, app: &mut App, area: Rect) {
let constraints = if app.show_chart {
vec![Constraint::Percentage(50), Constraint::Percentage(50)]
} else {
vec![Constraint::Percentage(100)]
};
let chunks = Layout::horizontal(constraints).split(area);
{
let chunks = Layout::vertical([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[0]);
{
let chunks =
Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[0]);
// Draw tasks
let tasks: Vec<ListItem> = app
.tasks
.items
.iter()
.map(|i| ListItem::new(vec![text::Line::from(Span::raw(*i))]))
.collect();
let tasks = List::new(tasks)
.block(Block::bordered().title("List"))
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
.highlight_symbol("> ");
f.render_stateful_widget(tasks, chunks[0], &mut app.tasks.state);
// Draw logs
let info_style = Style::default().fg(Color::Blue);
let warning_style = Style::default().fg(Color::Yellow);
let error_style = Style::default().fg(Color::Magenta);
let critical_style = Style::default().fg(Color::Red);
let logs: Vec<ListItem> = app
.logs
.items
.iter()
.map(|&(evt, level)| {
let s = match level {
"ERROR" => error_style,
"CRITICAL" => critical_style,
"WARNING" => warning_style,
_ => info_style,
};
let content = vec![text::Line::from(vec![
Span::styled(format!("{level:<9}"), s),
Span::raw(evt),
])];
ListItem::new(content)
})
.collect();
let logs = List::new(logs).block(Block::bordered().title("List"));
f.render_stateful_widget(logs, chunks[1], &mut app.logs.state);
}
let barchart = BarChart::default()
.block(Block::bordered().title("Bar chart"))
.data(&app.barchart)
.bar_width(3)
.bar_gap(2)
.bar_set(if app.enhanced_graphics {
symbols::bar::NINE_LEVELS
} else {
symbols::bar::THREE_LEVELS
})
.value_style(
Style::default()
.fg(Color::Black)
.bg(Color::Green)
.add_modifier(Modifier::ITALIC),
)
.label_style(Style::default().fg(Color::Yellow))
.bar_style(Style::default().fg(Color::Green));
f.render_widget(barchart, chunks[1]);
}
if app.show_chart {
let x_labels = vec![
Span::styled(
format!("{}", app.signals.window[0]),
Style::default().add_modifier(Modifier::BOLD),
),
Span::raw(format!(
"{}",
(app.signals.window[0] + app.signals.window[1]) / 2.0
)),
Span::styled(
format!("{}", app.signals.window[1]),
Style::default().add_modifier(Modifier::BOLD),
),
];
let datasets = vec![
Dataset::default()
.name("data2")
.marker(symbols::Marker::Dot)
.style(Style::default().fg(Color::Cyan))
.data(&app.signals.sin1.points),
Dataset::default()
.name("data3")
.marker(if app.enhanced_graphics {
symbols::Marker::Braille
} else {
symbols::Marker::Dot
})
.style(Style::default().fg(Color::Yellow))
.data(&app.signals.sin2.points),
];
let chart = Chart::new(datasets)
.block(
Block::bordered().title(Span::styled(
"Chart",
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
)),
)
.x_axis(
Axis::default()
.title("X Axis")
.style(Style::default().fg(Color::Gray))
.bounds(app.signals.window)
.labels(x_labels),
)
.y_axis(
Axis::default()
.title("Y Axis")
.style(Style::default().fg(Color::Gray))
.bounds([-20.0, 20.0])
.labels(vec![
Span::styled("-20", Style::default().add_modifier(Modifier::BOLD)),
Span::raw("0"),
Span::styled("20", Style::default().add_modifier(Modifier::BOLD)),
]),
);
f.render_widget(chart, chunks[1]);
}
}
sourcepub fn style<S: Into<Style>>(self, style: S) -> Self
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
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.
let list = List::new(items).red().italic();
Examples found in repository?
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
let [tabs, inbox] = vertical.areas(area);
let theme = THEME.email;
Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
.style(theme.tabs)
.highlight_style(theme.tabs_selected)
.select(0)
.divider("")
.render(tabs, buf);
let highlight_symbol = ">>";
let from_width = EMAILS
.iter()
.map(|e| e.from.width())
.max()
.unwrap_or_default();
let items = EMAILS
.iter()
.map(|e| {
let from = format!("{:width$}", e.from, width = from_width).into();
ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
})
.collect_vec();
let mut state = ListState::default().with_selected(Some(selected_index));
StatefulWidget::render(
List::new(items)
.style(theme.inbox)
.highlight_style(theme.selected_item)
.highlight_symbol(highlight_symbol),
inbox,
buf,
&mut state,
);
let mut scrollbar_state = ScrollbarState::default()
.content_length(EMAILS.len())
.position(selected_index);
Scrollbar::default()
.begin_symbol(None)
.end_symbol(None)
.track_symbol(None)
.thumb_symbol("▐")
.render(inbox, buf, &mut scrollbar_state);
}
sourcepub const fn highlight_symbol(self, highlight_symbol: &'a str) -> Self
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
let list = List::new(items).highlight_symbol(">>");
Examples found in repository?
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
let [tabs, inbox] = vertical.areas(area);
let theme = THEME.email;
Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
.style(theme.tabs)
.highlight_style(theme.tabs_selected)
.select(0)
.divider("")
.render(tabs, buf);
let highlight_symbol = ">>";
let from_width = EMAILS
.iter()
.map(|e| e.from.width())
.max()
.unwrap_or_default();
let items = EMAILS
.iter()
.map(|e| {
let from = format!("{:width$}", e.from, width = from_width).into();
ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
})
.collect_vec();
let mut state = ListState::default().with_selected(Some(selected_index));
StatefulWidget::render(
List::new(items)
.style(theme.inbox)
.highlight_style(theme.selected_item)
.highlight_symbol(highlight_symbol),
inbox,
buf,
&mut state,
);
let mut scrollbar_state = ScrollbarState::default()
.content_length(EMAILS.len())
.position(selected_index);
Scrollbar::default()
.begin_symbol(None)
.end_symbol(None)
.track_symbol(None)
.thumb_symbol("▐")
.render(inbox, buf, &mut scrollbar_state);
}
More examples
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
fn render_todo(&mut self, area: Rect, buf: &mut Buffer) {
// We create two blocks, one is for the header (outer) and the other is for list (inner).
let outer_block = Block::new()
.borders(Borders::NONE)
.title_alignment(Alignment::Center)
.title("TODO List")
.fg(TEXT_COLOR)
.bg(TODO_HEADER_BG);
let inner_block = Block::new()
.borders(Borders::NONE)
.fg(TEXT_COLOR)
.bg(NORMAL_ROW_COLOR);
// We get the inner area from outer_block. We'll use this area later to render the table.
let outer_area = area;
let inner_area = outer_block.inner(outer_area);
// We can render the header in outer_area.
outer_block.render(outer_area, buf);
// Iterate through all elements in the `items` and stylize them.
let items: Vec<ListItem> = self
.items
.items
.iter()
.enumerate()
.map(|(i, todo_item)| todo_item.to_list_item(i))
.collect();
// Create a List from all list items and highlight the currently selected one
let items = List::new(items)
.block(inner_block)
.highlight_style(
Style::default()
.add_modifier(Modifier::BOLD)
.add_modifier(Modifier::REVERSED)
.fg(SELECTED_STYLE_FG),
)
.highlight_symbol(">")
.highlight_spacing(HighlightSpacing::Always);
// We can now render the item list
// (look careful we are using StatefulWidget's render.)
// ratatui::widgets::StatefulWidget::render as stateful_render
StatefulWidget::render(items, inner_area, buf, &mut self.items.state);
}
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
fn draw_charts(f: &mut Frame, app: &mut App, area: Rect) {
let constraints = if app.show_chart {
vec![Constraint::Percentage(50), Constraint::Percentage(50)]
} else {
vec![Constraint::Percentage(100)]
};
let chunks = Layout::horizontal(constraints).split(area);
{
let chunks = Layout::vertical([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[0]);
{
let chunks =
Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[0]);
// Draw tasks
let tasks: Vec<ListItem> = app
.tasks
.items
.iter()
.map(|i| ListItem::new(vec![text::Line::from(Span::raw(*i))]))
.collect();
let tasks = List::new(tasks)
.block(Block::bordered().title("List"))
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
.highlight_symbol("> ");
f.render_stateful_widget(tasks, chunks[0], &mut app.tasks.state);
// Draw logs
let info_style = Style::default().fg(Color::Blue);
let warning_style = Style::default().fg(Color::Yellow);
let error_style = Style::default().fg(Color::Magenta);
let critical_style = Style::default().fg(Color::Red);
let logs: Vec<ListItem> = app
.logs
.items
.iter()
.map(|&(evt, level)| {
let s = match level {
"ERROR" => error_style,
"CRITICAL" => critical_style,
"WARNING" => warning_style,
_ => info_style,
};
let content = vec![text::Line::from(vec![
Span::styled(format!("{level:<9}"), s),
Span::raw(evt),
])];
ListItem::new(content)
})
.collect();
let logs = List::new(logs).block(Block::bordered().title("List"));
f.render_stateful_widget(logs, chunks[1], &mut app.logs.state);
}
let barchart = BarChart::default()
.block(Block::bordered().title("Bar chart"))
.data(&app.barchart)
.bar_width(3)
.bar_gap(2)
.bar_set(if app.enhanced_graphics {
symbols::bar::NINE_LEVELS
} else {
symbols::bar::THREE_LEVELS
})
.value_style(
Style::default()
.fg(Color::Black)
.bg(Color::Green)
.add_modifier(Modifier::ITALIC),
)
.label_style(Style::default().fg(Color::Yellow))
.bar_style(Style::default().fg(Color::Green));
f.render_widget(barchart, chunks[1]);
}
if app.show_chart {
let x_labels = vec![
Span::styled(
format!("{}", app.signals.window[0]),
Style::default().add_modifier(Modifier::BOLD),
),
Span::raw(format!(
"{}",
(app.signals.window[0] + app.signals.window[1]) / 2.0
)),
Span::styled(
format!("{}", app.signals.window[1]),
Style::default().add_modifier(Modifier::BOLD),
),
];
let datasets = vec![
Dataset::default()
.name("data2")
.marker(symbols::Marker::Dot)
.style(Style::default().fg(Color::Cyan))
.data(&app.signals.sin1.points),
Dataset::default()
.name("data3")
.marker(if app.enhanced_graphics {
symbols::Marker::Braille
} else {
symbols::Marker::Dot
})
.style(Style::default().fg(Color::Yellow))
.data(&app.signals.sin2.points),
];
let chart = Chart::new(datasets)
.block(
Block::bordered().title(Span::styled(
"Chart",
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
)),
)
.x_axis(
Axis::default()
.title("X Axis")
.style(Style::default().fg(Color::Gray))
.bounds(app.signals.window)
.labels(x_labels),
)
.y_axis(
Axis::default()
.title("Y Axis")
.style(Style::default().fg(Color::Gray))
.bounds([-20.0, 20.0])
.labels(vec![
Span::styled("-20", Style::default().add_modifier(Modifier::BOLD)),
Span::raw("0"),
Span::styled("20", Style::default().add_modifier(Modifier::BOLD)),
]),
);
f.render_widget(chart, chunks[1]);
}
}
sourcepub fn highlight_style<S: Into<Style>>(self, style: S) -> Self
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
let list = List::new(items).highlight_style(Style::new().red().italic());
Examples found in repository?
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
fn render_inbox(selected_index: usize, area: Rect, buf: &mut Buffer) {
let vertical = Layout::vertical([Constraint::Length(1), Constraint::Min(0)]);
let [tabs, inbox] = vertical.areas(area);
let theme = THEME.email;
Tabs::new(vec![" Inbox ", " Sent ", " Drafts "])
.style(theme.tabs)
.highlight_style(theme.tabs_selected)
.select(0)
.divider("")
.render(tabs, buf);
let highlight_symbol = ">>";
let from_width = EMAILS
.iter()
.map(|e| e.from.width())
.max()
.unwrap_or_default();
let items = EMAILS
.iter()
.map(|e| {
let from = format!("{:width$}", e.from, width = from_width).into();
ListItem::new(Line::from(vec![from, " ".into(), e.subject.into()]))
})
.collect_vec();
let mut state = ListState::default().with_selected(Some(selected_index));
StatefulWidget::render(
List::new(items)
.style(theme.inbox)
.highlight_style(theme.selected_item)
.highlight_symbol(highlight_symbol),
inbox,
buf,
&mut state,
);
let mut scrollbar_state = ScrollbarState::default()
.content_length(EMAILS.len())
.position(selected_index);
Scrollbar::default()
.begin_symbol(None)
.end_symbol(None)
.track_symbol(None)
.thumb_symbol("▐")
.render(inbox, buf, &mut scrollbar_state);
}
More examples
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
fn render_todo(&mut self, area: Rect, buf: &mut Buffer) {
// We create two blocks, one is for the header (outer) and the other is for list (inner).
let outer_block = Block::new()
.borders(Borders::NONE)
.title_alignment(Alignment::Center)
.title("TODO List")
.fg(TEXT_COLOR)
.bg(TODO_HEADER_BG);
let inner_block = Block::new()
.borders(Borders::NONE)
.fg(TEXT_COLOR)
.bg(NORMAL_ROW_COLOR);
// We get the inner area from outer_block. We'll use this area later to render the table.
let outer_area = area;
let inner_area = outer_block.inner(outer_area);
// We can render the header in outer_area.
outer_block.render(outer_area, buf);
// Iterate through all elements in the `items` and stylize them.
let items: Vec<ListItem> = self
.items
.items
.iter()
.enumerate()
.map(|(i, todo_item)| todo_item.to_list_item(i))
.collect();
// Create a List from all list items and highlight the currently selected one
let items = List::new(items)
.block(inner_block)
.highlight_style(
Style::default()
.add_modifier(Modifier::BOLD)
.add_modifier(Modifier::REVERSED)
.fg(SELECTED_STYLE_FG),
)
.highlight_symbol(">")
.highlight_spacing(HighlightSpacing::Always);
// We can now render the item list
// (look careful we are using StatefulWidget's render.)
// ratatui::widgets::StatefulWidget::render as stateful_render
StatefulWidget::render(items, inner_area, buf, &mut self.items.state);
}
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
fn draw_charts(f: &mut Frame, app: &mut App, area: Rect) {
let constraints = if app.show_chart {
vec![Constraint::Percentage(50), Constraint::Percentage(50)]
} else {
vec![Constraint::Percentage(100)]
};
let chunks = Layout::horizontal(constraints).split(area);
{
let chunks = Layout::vertical([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[0]);
{
let chunks =
Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)])
.split(chunks[0]);
// Draw tasks
let tasks: Vec<ListItem> = app
.tasks
.items
.iter()
.map(|i| ListItem::new(vec![text::Line::from(Span::raw(*i))]))
.collect();
let tasks = List::new(tasks)
.block(Block::bordered().title("List"))
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
.highlight_symbol("> ");
f.render_stateful_widget(tasks, chunks[0], &mut app.tasks.state);
// Draw logs
let info_style = Style::default().fg(Color::Blue);
let warning_style = Style::default().fg(Color::Yellow);
let error_style = Style::default().fg(Color::Magenta);
let critical_style = Style::default().fg(Color::Red);
let logs: Vec<ListItem> = app
.logs
.items
.iter()
.map(|&(evt, level)| {
let s = match level {
"ERROR" => error_style,
"CRITICAL" => critical_style,
"WARNING" => warning_style,
_ => info_style,
};
let content = vec![text::Line::from(vec![
Span::styled(format!("{level:<9}"), s),
Span::raw(evt),
])];
ListItem::new(content)
})
.collect();
let logs = List::new(logs).block(Block::bordered().title("List"));
f.render_stateful_widget(logs, chunks[1], &mut app.logs.state);
}
let barchart = BarChart::default()
.block(Block::bordered().title("Bar chart"))
.data(&app.barchart)
.bar_width(3)
.bar_gap(2)
.bar_set(if app.enhanced_graphics {
symbols::bar::NINE_LEVELS
} else {
symbols::bar::THREE_LEVELS
})
.value_style(
Style::default()
.fg(Color::Black)
.bg(Color::Green)
.add_modifier(Modifier::ITALIC),
)
.label_style(Style::default().fg(Color::Yellow))
.bar_style(Style::default().fg(Color::Green));
f.render_widget(barchart, chunks[1]);
}
if app.show_chart {
let x_labels = vec![
Span::styled(
format!("{}", app.signals.window[0]),
Style::default().add_modifier(Modifier::BOLD),
),
Span::raw(format!(
"{}",
(app.signals.window[0] + app.signals.window[1]) / 2.0
)),
Span::styled(
format!("{}", app.signals.window[1]),
Style::default().add_modifier(Modifier::BOLD),
),
];
let datasets = vec![
Dataset::default()
.name("data2")
.marker(symbols::Marker::Dot)
.style(Style::default().fg(Color::Cyan))
.data(&app.signals.sin1.points),
Dataset::default()
.name("data3")
.marker(if app.enhanced_graphics {
symbols::Marker::Braille
} else {
symbols::Marker::Dot
})
.style(Style::default().fg(Color::Yellow))
.data(&app.signals.sin2.points),
];
let chart = Chart::new(datasets)
.block(
Block::bordered().title(Span::styled(
"Chart",
Style::default()
.fg(Color::Cyan)
.add_modifier(Modifier::BOLD),
)),
)
.x_axis(
Axis::default()
.title("X Axis")
.style(Style::default().fg(Color::Gray))
.bounds(app.signals.window)
.labels(x_labels),
)
.y_axis(
Axis::default()
.title("Y Axis")
.style(Style::default().fg(Color::Gray))
.bounds([-20.0, 20.0])
.labels(vec![
Span::styled("-20", Style::default().add_modifier(Modifier::BOLD)),
Span::raw("0"),
Span::styled("20", Style::default().add_modifier(Modifier::BOLD)),
]),
);
f.render_widget(chart, chunks[1]);
}
}
sourcepub const fn repeat_highlight_symbol(self, repeat: bool) -> Self
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
sourcepub const fn highlight_spacing(self, value: HighlightSpacing) -> Self
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 useHighlightSpacing::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
let list = List::new(items).highlight_spacing(HighlightSpacing::Always);
Examples found in repository?
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
fn render_todo(&mut self, area: Rect, buf: &mut Buffer) {
// We create two blocks, one is for the header (outer) and the other is for list (inner).
let outer_block = Block::new()
.borders(Borders::NONE)
.title_alignment(Alignment::Center)
.title("TODO List")
.fg(TEXT_COLOR)
.bg(TODO_HEADER_BG);
let inner_block = Block::new()
.borders(Borders::NONE)
.fg(TEXT_COLOR)
.bg(NORMAL_ROW_COLOR);
// We get the inner area from outer_block. We'll use this area later to render the table.
let outer_area = area;
let inner_area = outer_block.inner(outer_area);
// We can render the header in outer_area.
outer_block.render(outer_area, buf);
// Iterate through all elements in the `items` and stylize them.
let items: Vec<ListItem> = self
.items
.items
.iter()
.enumerate()
.map(|(i, todo_item)| todo_item.to_list_item(i))
.collect();
// Create a List from all list items and highlight the currently selected one
let items = List::new(items)
.block(inner_block)
.highlight_style(
Style::default()
.add_modifier(Modifier::BOLD)
.add_modifier(Modifier::REVERSED)
.fg(SELECTED_STYLE_FG),
)
.highlight_symbol(">")
.highlight_spacing(HighlightSpacing::Always);
// We can now render the item list
// (look careful we are using StatefulWidget's render.)
// ratatui::widgets::StatefulWidget::render as stateful_render
StatefulWidget::render(items, inner_area, buf, &mut self.items.state);
}
sourcepub const fn direction(self, direction: ListDirection) -> Self
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
let list = List::new(items).direction(ListDirection::BottomToTop);
sourcepub const fn scroll_padding(self, padding: usize) -> Self
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
let list = List::new(items).scroll_padding(1);
sourcepub fn start_corner(self, corner: Corner) -> Self
👎Deprecated since 0.25.0: You should use List::direction
instead.
pub fn start_corner(self, corner: Corner) -> Self
List::direction
instead.Defines the list direction (up or down)
Defines if the List
is displayed top to bottom (default) or bottom to top. Use
Corner::BottomLeft
to go bottom to top. Any other variant will go top to bottom.
If there is too few items to fill the screen, the list will stick to the starting edge.
This is set to Corner::TopLeft
by default.
This is a fluent setter method which must be chained or used as it consumes self
§Note
Despite its name, this method doesn’t change the horizontal alignment, i.e. the List
won’t start in a corner.
§Example
Same as default, i.e. top to bottom. Despite the name implying otherwise.
let list = List::new(items).start_corner(Corner::BottomRight);
Bottom to top
let list = List::new(items).start_corner(Corner::BottomLeft);
Trait Implementations§
source§impl<'a, Item> FromIterator<Item> for List<'a>
impl<'a, Item> FromIterator<Item> for List<'a>
source§fn from_iter<Iter: IntoIterator<Item = Item>>(iter: Iter) -> Self
fn from_iter<Iter: IntoIterator<Item = Item>>(iter: Iter) -> Self
source§impl<'a> PartialEq for List<'a>
impl<'a> PartialEq for List<'a>
source§impl StatefulWidget for &List<'_>
impl StatefulWidget for &List<'_>
source§impl StatefulWidget for List<'_>
impl StatefulWidget for List<'_>
source§impl StatefulWidgetRef for List<'_>
impl StatefulWidgetRef for List<'_>
source§impl WidgetRef for List<'_>
impl WidgetRef for List<'_>
source§fn render_ref(&self, area: Rect, buf: &mut Buffer)
fn render_ref(&self, area: Rect, buf: &mut Buffer)
unstable-widget-ref
only.impl<'a> Eq for List<'a>
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<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 moresource§impl<'a, T, U> Stylize<'a, T> for Uwhere
U: Styled<Item = T>,
impl<'a, T, U> Stylize<'a, T> for Uwhere
U: Styled<Item = T>,
fn bg(self, color: Color) -> T
fn fg<S>(self, color: S) -> T
fn add_modifier(self, modifier: Modifier) -> T
fn remove_modifier(self, modifier: Modifier) -> T
fn reset(self) -> T
source§fn on_magenta(self) -> T
fn on_magenta(self) -> T
magenta
.source§fn on_dark_gray(self) -> T
fn on_dark_gray(self) -> T
dark_gray
.source§fn on_light_red(self) -> T
fn on_light_red(self) -> T
light_red
.source§fn light_green(self) -> T
fn light_green(self) -> T
light_green
.source§fn on_light_green(self) -> T
fn on_light_green(self) -> T
light_green
.source§fn light_yellow(self) -> T
fn light_yellow(self) -> T
light_yellow
.source§fn on_light_yellow(self) -> T
fn on_light_yellow(self) -> T
light_yellow
.source§fn light_blue(self) -> T
fn light_blue(self) -> T
light_blue
.source§fn on_light_blue(self) -> T
fn on_light_blue(self) -> T
light_blue
.source§fn light_magenta(self) -> T
fn light_magenta(self) -> T
light_magenta
.source§fn on_light_magenta(self) -> T
fn on_light_magenta(self) -> T
light_magenta
.source§fn light_cyan(self) -> T
fn light_cyan(self) -> T
light_cyan
.source§fn on_light_cyan(self) -> T
fn on_light_cyan(self) -> T
light_cyan
.source§fn not_italic(self) -> T
fn not_italic(self) -> T
ITALIC
modifier.source§fn underlined(self) -> T
fn underlined(self) -> T
UNDERLINED
modifier.source§fn not_underlined(self) -> T
fn not_underlined(self) -> T
UNDERLINED
modifier.source§fn slow_blink(self) -> T
fn slow_blink(self) -> T
SLOW_BLINK
modifier.source§fn not_slow_blink(self) -> T
fn not_slow_blink(self) -> T
SLOW_BLINK
modifier.source§fn rapid_blink(self) -> T
fn rapid_blink(self) -> T
RAPID_BLINK
modifier.source§fn not_rapid_blink(self) -> T
fn not_rapid_blink(self) -> T
RAPID_BLINK
modifier.source§fn not_reversed(self) -> T
fn not_reversed(self) -> T
REVERSED
modifier.HIDDEN
modifier.HIDDEN
modifier.source§fn crossed_out(self) -> T
fn crossed_out(self) -> T
CROSSED_OUT
modifier.source§fn not_crossed_out(self) -> T
fn not_crossed_out(self) -> T
CROSSED_OUT
modifier.