pub trait ItemDelegate<I: Item> {
// Required methods
fn render(&self, m: &Model<I>, index: usize, item: &I) -> String;
fn height(&self) -> usize;
fn spacing(&self) -> usize;
fn update(&self, msg: &Msg, m: &mut Model<I>) -> Option<Cmd>;
// Provided methods
fn short_help(&self) -> Vec<Binding> { ... }
fn full_help(&self) -> Vec<Vec<Binding>> { ... }
fn on_select(&self, _index: usize, _item: &I) -> Option<Cmd> { ... }
fn on_remove(&self, _index: usize, _item: &I) -> Option<Cmd> { ... }
fn can_remove(&self, _index: usize, _item: &I) -> bool { ... }
}Expand description
Core traits and types for list functionality.
These are the fundamental building blocks for creating custom list items and delegates:
Item: Trait for displayable and filterable list itemsItemDelegate: Trait for customizing item rendering and behaviorFilterState: Enum representing the current filtering stateFilterStateInfo: Detailed information about filter status
§Examples
use bubbletea_widgets::list::{Item, ItemDelegate, FilterState, Model};
use std::fmt::Display;
#[derive(Clone)]
struct MyItem {
name: String,
value: i32,
}
impl Display for MyItem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.name, self.value)
}
}
impl Item for MyItem {
fn filter_value(&self) -> String {
format!("{} {}", self.name, self.value)
}
}Trait for customizing how list items are rendered and behave.
The ItemDelegate trait allows you to completely customize the appearance and behavior of items in a list. This includes rendering individual items, defining their height and spacing, and handling custom update logic.
§Examples
// Multi-line delegate that shows item + description
struct DetailedDelegate;
impl<I: Item> ItemDelegate<I> for DetailedDelegate {
fn height(&self) -> usize {
2 // Title line + description line
}
}Required Methods§
Sourcefn render(&self, m: &Model<I>, index: usize, item: &I) -> String
fn render(&self, m: &Model<I>, index: usize, item: &I) -> String
Renders an item as a string for display in the list.
This method is called for each visible item and should return a styled string representation. The method receives the complete model state, the item’s original index, and the item itself.
§Arguments
m- The complete list model with current stateindex- The original index of this item in the full items listitem- The item to render
§Returns
A formatted string with any necessary ANSI styling codes.
§Examples
struct CustomDelegate;
impl<I: Item + Send + Sync + 'static> ItemDelegate<I> for CustomDelegate {
fn render(&self, m: &Model<I>, index: usize, item: &I) -> String {
if index == m.cursor() {
format!("> {}", item) // Highlight selected item
} else {
format!(" {}", item) // Normal item
}
}
}Sourcefn height(&self) -> usize
fn height(&self) -> usize
Returns the height in terminal lines that each item occupies.
This value is used by the list for layout calculations, viewport sizing, and scroll positioning. It should include any line breaks or multi-line content in your rendered items.
§Returns
The number of terminal lines each item will occupy when rendered.
§Examples
struct MultiLineDelegate;
impl<I: Item> ItemDelegate<I> for MultiLineDelegate {
fn height(&self) -> usize {
3 // Item title + description + blank line
}
}Sourcefn spacing(&self) -> usize
fn spacing(&self) -> usize
Returns the number of blank lines to insert between items.
This spacing is added between each item in the list to improve
readability and visual separation. The spacing is in addition to
the height returned by height().
§Returns
The number of blank lines to insert between rendered items.
Sourcefn update(&self, msg: &Msg, m: &mut Model<I>) -> Option<Cmd>
fn update(&self, msg: &Msg, m: &mut Model<I>) -> Option<Cmd>
Handles update messages for the delegate.
This method allows delegates to respond to messages and potentially
modify the list state or return commands. Most delegates don’t need
custom update logic and can return None.
§Arguments
msg- The message to handlem- Mutable reference to the list model
§Returns
An optional command to be executed by the runtime.
§Examples
struct InteractiveDelegate;
impl<I: Item> ItemDelegate<I> for InteractiveDelegate {
fn update(&self, msg: &Msg, m: &mut Model<I>) -> Option<Cmd> {
// Example: Handle custom key press
if let Some(key_msg) = msg.downcast_ref::<KeyMsg>() {
if key_msg.key == KeyCode::Char(' ') {
// Custom space key behavior
return None;
}
}
None
}
}Provided Methods§
Sourcefn short_help(&self) -> Vec<Binding>
fn short_help(&self) -> Vec<Binding>
Returns key bindings for the short help view.
This method provides a compact set of key bindings that will be displayed in short help views. The bindings should represent the most important or commonly used actions for this delegate.
§Returns
A vector of key bindings for compact help display.
§Examples
struct HelpfulDelegate {
select_key: key::Binding,
}
impl<I: Item> ItemDelegate<I> for HelpfulDelegate {
fn short_help(&self) -> Vec<key::Binding> {
vec![self.select_key.clone()]
}
}Sourcefn full_help(&self) -> Vec<Vec<Binding>>
fn full_help(&self) -> Vec<Vec<Binding>>
Returns key bindings for the full help view.
This method organizes all key bindings into columns for display in expanded help views. Each inner vector represents a column of related key bindings.
§Returns
A vector of vectors, where each inner vector represents a column of related key bindings.
§Examples
struct OrganizedDelegate {
navigation_keys: Vec<key::Binding>,
action_keys: Vec<key::Binding>,
}
impl<I: Item> ItemDelegate<I> for OrganizedDelegate {
fn full_help(&self) -> Vec<Vec<key::Binding>> {
vec![
self.navigation_keys.clone(),
self.action_keys.clone(),
]
}
}Sourcefn on_select(&self, _index: usize, _item: &I) -> Option<Cmd>
fn on_select(&self, _index: usize, _item: &I) -> Option<Cmd>
Called when an item is selected (e.g., Enter key pressed).
This method is invoked when the user selects an item, typically by pressing Enter. It allows the delegate to perform custom actions or return commands in response to item selection.
§Arguments
index- The index of the selected item in the original items listitem- A reference to the selected item
§Returns
An optional command to execute in response to the selection.
§Examples
struct SelectableDelegate;
impl<I: Item> ItemDelegate<I> for SelectableDelegate {
fn on_select(&self, index: usize, item: &I) -> Option<Cmd> {
// Log the selection and return a custom command
println!("Selected item {} at index {}", item, index);
None // Or return Some(your_command)
}
}Sourcefn on_remove(&self, _index: usize, _item: &I) -> Option<Cmd>
fn on_remove(&self, _index: usize, _item: &I) -> Option<Cmd>
Called when an item is about to be removed.
This method is invoked before an item is removed from the list, allowing the delegate to perform cleanup actions or return commands. Note that this is called by the list’s removal methods, not automatically by user actions.
§Arguments
index- The index of the item being removeditem- A reference to the item being removed
§Returns
An optional command to execute in response to the removal.
§Examples
struct TrackingDelegate;
impl<I: Item> ItemDelegate<I> for TrackingDelegate {
fn on_remove(&self, index: usize, item: &I) -> Option<Cmd> {
// Log the removal
println!("Removing item {} at index {}", item, index);
None
}
}Sourcefn can_remove(&self, _index: usize, _item: &I) -> bool
fn can_remove(&self, _index: usize, _item: &I) -> bool
Determines whether an item can be removed.
This method is called by the list to determine if an item at a given index is allowed to be removed. This can be used to implement protection for certain items or conditional removal logic.
§Arguments
index- The index of the item being checked for removalitem- A reference to the item being checked
§Returns
true if the item can be removed, false otherwise.
§Examples
struct ProtectedDelegate;
impl<I: Item> ItemDelegate<I> for ProtectedDelegate {
fn can_remove(&self, index: usize, item: &I) -> bool {
// Don't allow removal of the first item
index != 0
}
}