ItemDelegate

Trait ItemDelegate 

Source
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 items
  • ItemDelegate: Trait for customizing item rendering and behavior
  • FilterState: Enum representing the current filtering state
  • FilterStateInfo: 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§

Source

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 state
  • index - The original index of this item in the full items list
  • item - 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
        }
    }
}
Source

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
    }
}
Source

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.

Source

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 handle
  • m - 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§

Source

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()]
    }
     
}
Source

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(),
        ]
    }
     
}
Source

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 list
  • item - 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)
    }
     
}
Source

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 removed
  • item - 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
    }
     
}
Source

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 removal
  • item - 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
    }
     
}

Implementors§

Source§

impl<I: Item + 'static> ItemDelegate<I> for DefaultDelegate