Skip to content

Commit

Permalink
feat(List)!: new now accepts IntoIterator<Item = Into<ListItem>>
Browse files Browse the repository at this point in the history
This allows to build list like

```
List::new(["Item 1", "Item 2"])
```
  • Loading branch information
Valentin271 committed Dec 7, 2023
1 parent 3ec4e24 commit a57d0fe
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 18 deletions.
68 changes: 51 additions & 17 deletions src/widgets/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use crate::{
/// # use ratatui::{prelude::*, widgets::*};
/// # fn ui(frame: &mut Frame) {
/// # let area = Rect::default();
/// # let items = vec![];
/// # let items = vec!["Item 1"];
/// let list = List::new(items);
///
/// // This should be stored outside of the function in your application state.
Expand Down Expand Up @@ -178,6 +178,13 @@ impl ListState {
/// let item = ListItem::new("Item 1");
/// ```
///
/// Anything that can be converted to [`Text`] can be a [`ListItem`].
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// let item1: ListItem = "Item 1".into();
/// let item2: ListItem = Line::raw("Item 2").into();
/// ```
///
/// A [`ListItem`] styled with [`Stylize`]
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
Expand Down Expand Up @@ -213,6 +220,13 @@ impl<'a> ListItem<'a> {
/// let item = ListItem::new("Item 1");
/// ```
///
/// Anything that can be converted to [`Text`] can be a [`ListItem`].
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// let item1: ListItem = "Item 1".into();
/// let item2: ListItem = Line::raw("Item 2").into();
/// ```
///
/// You can also create multilines item
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
Expand Down Expand Up @@ -300,6 +314,15 @@ impl<'a> ListItem<'a> {
}
}

impl<'a, T> From<T> for ListItem<'a>
where
T: Into<Text<'a>>,
{
fn from(value: T) -> Self {
ListItem::new(value)
}
}

/// A widget to display several items among which one can be selected (optional)
///
/// A list is a collection of [`ListItem`]s.
Expand Down Expand Up @@ -336,7 +359,7 @@ impl<'a> ListItem<'a> {
/// use ratatui::{prelude::*, widgets::*};
/// # fn ui(frame: &mut Frame) {
/// # let area = Rect::default();
/// let items = [ListItem::new("Item 1"), ListItem::new("Item 2"), ListItem::new("Item 3")];
/// let items = ["Item 1", "Item 2", "Item 3"];
/// let list = List::new(items)
/// .block(Block::default().title("List").borders(Borders::ALL))
/// .style(Style::default().fg(Color::White))
Expand All @@ -357,7 +380,7 @@ impl<'a> ListItem<'a> {
/// # let area = Rect::default();
/// // This should be stored outside of the function in your application state.
/// let mut state = ListState::default();
/// let items = [ListItem::new("Item 1"), ListItem::new("Item 2"), ListItem::new("Item 3")];
/// let items = ["Item 1", "Item 2", "Item 3"];
/// let list = List::new(items)
/// .block(Block::default().title("List").borders(Borders::ALL))
/// .highlight_style(Style::new().add_modifier(Modifier::REVERSED))
Expand Down Expand Up @@ -389,20 +412,26 @@ impl<'a> List<'a> {
///
/// # Example
///
/// From a slice of [`ListItem`]
/// From a slice of [`&str`]
/// ```
/// # use ratatui::{prelude::*, widgets::*};
/// let list = List::new(["Item 1", "Item 2"]);
/// ```
///
/// From styled text (aka [`Text`])
/// ```
/// # use ratatui::{prelude::*, widgets::*};
/// let items = [ListItem::new("Item 1"), ListItem::new("Item 2")];
/// let list = List::new(items);
/// let list = List::new(["Item 1", "Item 2"]);
/// ```
pub fn new<T>(items: T) -> List<'a>
where
T: Into<Vec<ListItem<'a>>>,
T: IntoIterator,
T::Item: Into<ListItem<'a>>,
{
List {
block: None,
style: Style::default(),
items: items.into(),
items: items.into_iter().map(|i| i.into()).collect(),
start_corner: Corner::TopLeft,
highlight_style: Style::default(),
highlight_symbol: None,
Expand All @@ -421,7 +450,7 @@ impl<'a> List<'a> {
///
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// # let items = vec![ListItem::new("Item 1")];
/// # let items = vec!["Item 1"];
/// let block = Block::default().title("List").borders(Borders::ALL);
/// let list = List::new(items).block(block);
/// ```
Expand All @@ -442,7 +471,7 @@ impl<'a> List<'a> {
///
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// # let items = vec![ListItem::new("Item 1")];
/// # let items = vec!["Item 1"];
/// let list = List::new(items).style(Style::new().red().italic());
/// ```
///
Expand All @@ -453,7 +482,7 @@ impl<'a> List<'a> {
///
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// # let items = vec![ListItem::new("Item 1")];
/// # let items = vec!["Item 1"];
/// let list = List::new(items).red().italic();
/// ```
#[must_use = "method moves the value of self and returns the modified value"]
Expand All @@ -472,7 +501,7 @@ impl<'a> List<'a> {
///
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// # let items = vec![ListItem::new("Item 1"), ListItem::new("Item 2")];
/// # let items = vec!["Item 1", "Item 2"];
/// let list = List::new(items).highlight_symbol(">>");
/// ```
#[must_use = "method moves the value of self and returns the modified value"]
Expand All @@ -493,7 +522,7 @@ impl<'a> List<'a> {
///
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// # let items = vec![ListItem::new("Item 1"), ListItem::new("Item 2")];
/// # let items = vec!["Item 1", "Item 2"];
/// let list = List::new(items).highlight_style(Style::new().red().italic());
/// ```
#[must_use = "method moves the value of self and returns the modified value"]
Expand Down Expand Up @@ -535,7 +564,7 @@ impl<'a> List<'a> {
///
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// # let items = vec![ListItem::new("Item 1")];
/// # let items = vec!["Item 1"];
/// let list = List::new(items).highlight_spacing(HighlightSpacing::Always);
/// ```
#[must_use = "method moves the value of self and returns the modified value"]
Expand Down Expand Up @@ -563,14 +592,14 @@ impl<'a> List<'a> {
/// Same as default, i.e. *top to bottom*. Despite the name implying otherwise.
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// # let items = vec![ListItem::new("Item 1")];
/// # let items = vec!["Item 1"];
/// let list = List::new(items).start_corner(Corner::BottomRight);
/// ```
///
/// Bottom to top
/// ```rust
/// # use ratatui::{prelude::*, widgets::*};
/// # let items = vec![ListItem::new("Item 1")];
/// # let items = vec!["Item 1"];
/// let list = List::new(items).start_corner(Corner::BottomLeft);
/// ```
#[must_use = "method moves the value of self and returns the modified value"]
Expand Down Expand Up @@ -1472,7 +1501,12 @@ mod tests {
#[test]
fn list_can_be_stylized() {
assert_eq!(
List::new(vec![]).black().on_white().bold().not_dim().style,
List::new::<Vec<&str>>(vec![])
.black()
.on_white()
.bold()
.not_dim()
.style,
Style::default()
.fg(Color::Black)
.bg(Color::White)
Expand Down
2 changes: 1 addition & 1 deletion tests/widgets_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn list_should_shows_the_length() {
assert_eq!(list.len(), 3);
assert!(!list.is_empty());

let empty_list = List::new(vec![]);
let empty_list = List::new::<Vec<&str>>(vec![]);
assert_eq!(empty_list.len(), 0);
assert!(empty_list.is_empty());
}
Expand Down

0 comments on commit a57d0fe

Please sign in to comment.