pub struct ListState { /* private fields */ }
Expand description
State of the List
widget
This state can be used to scroll through items and select one. When the list is rendered as a
stateful widget, the selected item will be highlighted and the list will be shifted to ensure
that the selected item is visible. This will modify the ListState
object passed to the
Frame::render_stateful_widget
method.
The state consists of two fields:
offset
: the index of the first item to be displayedselected
: the index of the selected item, which can beNone
if no item is selected
See the list in the Examples directory for a more in depth example of the various configuration options and for how to handle state.
§Example
use ratatui::{
layout::Rect,
widgets::{List, ListState},
Frame,
};
let items = ["Item 1"];
let list = List::new(items);
// This should be stored outside of the function in your application state.
let mut state = ListState::default();
*state.offset_mut() = 1; // display the second item and onwards
state.select(Some(3)); // select the forth item (0-indexed)
frame.render_stateful_widget(list, area, &mut state);
Implementations§
Source§impl ListState
impl ListState
Sourcepub const fn with_offset(self, offset: usize) -> Self
pub const fn with_offset(self, offset: usize) -> Self
Sets the index of the first item to be displayed
This is a fluent setter method which must be chained or used as it consumes self
§Examples
use ratatui::widgets::ListState;
let state = ListState::default().with_offset(1);
Sourcepub const fn with_selected(self, selected: Option<usize>) -> Self
pub const fn with_selected(self, selected: Option<usize>) -> Self
Sets the index of the selected item
This is a fluent setter method which must be chained or used as it consumes self
§Examples
use ratatui::widgets::ListState;
let state = ListState::default().with_selected(Some(1));
Examples found in repository?
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}
Sourcepub const fn offset(&self) -> usize
pub const fn offset(&self) -> usize
Index of the first item to be displayed
§Examples
use ratatui::widgets::ListState;
let state = ListState::default();
assert_eq!(state.offset(), 0);
Sourcepub fn offset_mut(&mut self) -> &mut usize
pub fn offset_mut(&mut self) -> &mut usize
Mutable reference to the index of the first item to be displayed
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
*state.offset_mut() = 1;
Sourcepub const fn selected(&self) -> Option<usize>
pub const fn selected(&self) -> Option<usize>
Index of the selected item
Returns None
if no item is selected
§Examples
use ratatui::widgets::ListState;
let state = ListState::default();
assert_eq!(state.selected(), None);
Examples found in repository?
164 fn toggle_status(&mut self) {
165 if let Some(i) = self.todo_list.state.selected() {
166 self.todo_list.items[i].status = match self.todo_list.items[i].status {
167 Status::Completed => Status::Todo,
168 Status::Todo => Status::Completed,
169 }
170 }
171 }
172}
173
174impl Widget for &mut App {
175 fn render(self, area: Rect, buf: &mut Buffer) {
176 let [header_area, main_area, footer_area] = Layout::vertical([
177 Constraint::Length(2),
178 Constraint::Fill(1),
179 Constraint::Length(1),
180 ])
181 .areas(area);
182
183 let [list_area, item_area] =
184 Layout::vertical([Constraint::Fill(1), Constraint::Fill(1)]).areas(main_area);
185
186 App::render_header(header_area, buf);
187 App::render_footer(footer_area, buf);
188 self.render_list(list_area, buf);
189 self.render_selected_item(item_area, buf);
190 }
191}
192
193/// Rendering logic for the app
194impl App {
195 fn render_header(area: Rect, buf: &mut Buffer) {
196 Paragraph::new("Ratatui List Example")
197 .bold()
198 .centered()
199 .render(area, buf);
200 }
201
202 fn render_footer(area: Rect, buf: &mut Buffer) {
203 Paragraph::new("Use ↓↑ to move, ← to unselect, → to change status, g/G to go top/bottom.")
204 .centered()
205 .render(area, buf);
206 }
207
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 }
239
240 fn render_selected_item(&self, area: Rect, buf: &mut Buffer) {
241 // We get the info depending on the item's state.
242 let info = if let Some(i) = self.todo_list.state.selected() {
243 match self.todo_list.items[i].status {
244 Status::Completed => format!("✓ DONE: {}", self.todo_list.items[i].info),
245 Status::Todo => format!("☐ TODO: {}", self.todo_list.items[i].info),
246 }
247 } else {
248 "Nothing selected...".to_string()
249 };
250
251 // We show the list item's info under the list in this paragraph
252 let block = Block::new()
253 .title(Line::raw("TODO Info").centered())
254 .borders(Borders::TOP)
255 .border_set(symbols::border::EMPTY)
256 .border_style(TODO_HEADER_STYLE)
257 .bg(NORMAL_ROW_BG)
258 .padding(Padding::horizontal(1));
259
260 // We can now render the item info
261 Paragraph::new(info)
262 .block(block)
263 .fg(TEXT_FG_COLOR)
264 .wrap(Wrap { trim: false })
265 .render(area, buf);
266 }
Sourcepub fn selected_mut(&mut self) -> &mut Option<usize>
pub fn selected_mut(&mut self) -> &mut Option<usize>
Mutable reference to the index of the selected item
Returns None
if no item is selected
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
*state.selected_mut() = Some(1);
Sourcepub fn select(&mut self, index: Option<usize>)
pub fn select(&mut self, index: Option<usize>)
Sets the index of the selected item
Set to None
if no item is selected. This will also reset the offset to 0
.
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
state.select(Some(1));
Sourcepub fn select_next(&mut self)
pub fn select_next(&mut self)
Selects the next item or the first one if no item is selected
Note: until the list is rendered, the number of items is not known, so the index is set to
0
and will be corrected when the list is rendered
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
state.select_next();
Sourcepub fn select_previous(&mut self)
pub fn select_previous(&mut self)
Selects the previous item or the last one if no item is selected
Note: until the list is rendered, the number of items is not known, so the index is set to
usize::MAX
and will be corrected when the list is rendered
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
state.select_previous();
Sourcepub fn select_first(&mut self)
pub fn select_first(&mut self)
Selects the first item
Note: until the list is rendered, the number of items is not known, so the index is set to
0
and will be corrected when the list is rendered
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
state.select_first();
Sourcepub fn select_last(&mut self)
pub fn select_last(&mut self)
Selects the last item
Note: until the list is rendered, the number of items is not known, so the index is set to
usize::MAX
and will be corrected when the list is rendered
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
state.select_last();
Sourcepub fn scroll_down_by(&mut self, amount: u16)
pub fn scroll_down_by(&mut self, amount: u16)
Scrolls down by a specified amount
in the list.
This method updates the selected index by moving it down by the given amount
.
If the amount
causes the index to go out of bounds (i.e., if the index is greater than
the length of the list), the last item in the list will be selected.
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
state.scroll_down_by(4);
Sourcepub fn scroll_up_by(&mut self, amount: u16)
pub fn scroll_up_by(&mut self, amount: u16)
Scrolls up by a specified amount
in the list.
This method updates the selected index by moving it up by the given amount
.
If the amount
causes the index to go out of bounds (i.e., less than zero),
the first item in the list will be selected.
§Examples
use ratatui::widgets::ListState;
let mut state = ListState::default();
state.scroll_up_by(4);
Trait Implementations§
Source§impl<'de> Deserialize<'de> for ListState
impl<'de> Deserialize<'de> for ListState
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for ListState
impl StructuralPartialEq for ListState
Auto Trait Implementations§
impl Freeze for ListState
impl RefUnwindSafe for ListState
impl Send for ListState
impl Sync for ListState
impl Unpin for ListState
impl UnwindSafe for ListState
Blanket Implementations§
Source§impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
T: Real + Zero + Arithmetics + Clone,
Swp: WhitePoint<T>,
Dwp: WhitePoint<T>,
D: AdaptFrom<S, Swp, Dwp, T>,
impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for Swhere
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) -> Dwhere
M: TransformMatrix<T>,
fn adapt_into_using<M>(self, method: M) -> Dwhere
M: TransformMatrix<T>,
Source§fn adapt_into(self) -> D
fn adapt_into(self) -> D
Source§impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
impl<T, C> ArraysFrom<C> for Twhere
C: IntoArrays<T>,
Source§fn arrays_from(colors: C) -> T
fn arrays_from(colors: C) -> T
Source§impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
impl<T, C> ArraysInto<C> for Twhere
C: FromArrays<T>,
Source§fn arrays_into(self) -> C
fn arrays_into(self) -> C
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<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for Uwhere
T: FromCam16Unclamped<WpParam, U>,
Source§type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn cam16_into_unclamped(
self,
parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>,
) -> T
fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
impl<T, C> ComponentsFrom<C> for Twhere
C: IntoComponents<T>,
Source§fn components_from(colors: C) -> T
fn components_from(colors: C) -> T
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.Source§impl<T> FromAngle<T> for T
impl<T> FromAngle<T> for T
Source§fn from_angle(angle: T) -> T
fn from_angle(angle: T) -> T
angle
.Source§impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
impl<T, U> FromStimulus<U> for Twhere
U: IntoStimulus<T>,
Source§fn from_stimulus(other: U) -> T
fn from_stimulus(other: U) -> T
other
into Self
, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
impl<T, U> IntoAngle<U> for Twhere
U: FromAngle<T>,
Source§fn into_angle(self) -> U
fn into_angle(self) -> U
T
.Source§impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for Uwhere
T: Cam16FromUnclamped<WpParam, U>,
Source§type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar
parameters
when converting.Source§fn into_cam16_unclamped(
self,
parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>,
) -> T
fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T
self
into C
, using the provided parameters.Source§impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
impl<T, U> IntoColor<U> for Twhere
U: FromColor<T>,
Source§fn into_color(self) -> U
fn into_color(self) -> U
Source§impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
impl<T, U> IntoColorUnclamped<U> for Twhere
U: FromColorUnclamped<T>,
Source§fn into_color_unclamped(self) -> U
fn into_color_unclamped(self) -> U
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<T> IntoStimulus<T> for T
impl<T> IntoStimulus<T> for T
Source§fn into_stimulus(self) -> T
fn into_stimulus(self) -> T
self
into T
, while performing the appropriate scaling,
rounding and clamping.Source§impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
impl<T, C> TryComponentsInto<C> for Twhere
C: TryFromComponents<T>,
Source§type Error = <C as TryFromComponents<T>>::Error
type Error = <C as TryFromComponents<T>>::Error
try_into_colors
fails to cast.Source§fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>
Source§impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
impl<T, U> TryIntoColor<U> for Twhere
U: TryFromColor<T>,
Source§fn try_into_color(self) -> Result<U, OutOfBounds<U>>
fn try_into_color(self) -> Result<U, OutOfBounds<U>>
OutOfBounds
error is returned which contains
the unclamped color. Read more