DefaultDelegate

Struct DefaultDelegate 

Source
pub struct DefaultDelegate {
    pub show_description: bool,
    pub styles: DefaultItemStyles,
    /* private fields */
}
Expand description

A delegate for rendering DefaultItem instances in list components.

This delegate provides the standard rendering logic for DefaultItem objects, handling different visual states, filtering highlights, and layout options. It implements the ItemDelegate trait to integrate seamlessly with the list component system.

§Features

  • Adaptive styling: Automatically adjusts colors for light/dark terminals
  • State rendering: Handles normal, selected, and dimmed visual states
  • Filter highlighting: Character-level highlighting of search matches
  • Flexible layout: Configurable description display and item spacing
  • Responsive design: Adjusts rendering based on available width

§Configuration

The delegate can be customized through its public fields:

  • show_description: Controls whether descriptions are rendered below titles
  • styles: Complete styling configuration for all visual states

§Usage with List

The delegate is designed to work with the Model<DefaultItem> list component and handles all the rendering complexity automatically.

§Examples

use bubbletea_widgets::list::{DefaultDelegate, DefaultItem, Model};

// Create a delegate with default settings
let delegate = DefaultDelegate::new();

// Customize the delegate
let mut custom_delegate = DefaultDelegate::new();
custom_delegate.show_description = false; // Hide descriptions

// Use with a list
let items = vec![
    DefaultItem::new("Task 1", "First task description"),
    DefaultItem::new("Task 2", "Second task description"),
];
let list = Model::new(items, delegate, 80, 24);

Fields§

§show_description: bool

Whether to show the description beneath the title.

§styles: DefaultItemStyles

Styling used for different visual states.

Implementations§

Source§

impl DefaultDelegate

Source

pub fn new() -> Self

Creates a new delegate with default styles and layout.

This is equivalent to DefaultDelegate::default() and provides a convenient constructor for creating a new delegate with standard settings.

§Returns

A new DefaultDelegate configured with default settings suitable for most list use cases.

§Examples
use bubbletea_widgets::list::{DefaultDelegate, DefaultItem, Model};

let delegate = DefaultDelegate::new();
let items = vec![DefaultItem::new("Item 1", "Description 1")];
let list = Model::new(items, delegate, 80, 24);

Trait Implementations§

Source§

impl Clone for DefaultDelegate

Source§

fn clone(&self) -> DefaultDelegate

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DefaultDelegate

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for DefaultDelegate

Source§

fn default() -> Self

Creates a new delegate with default configuration.

The default delegate is configured with:

  • Description display enabled
  • Standard adaptive styling
  • Height of 2 lines (title + description)
  • 1 line spacing between items

This configuration provides a standard list appearance that matches the Go bubbles library defaults.

§Examples
use bubbletea_widgets::list::DefaultDelegate;

let delegate = DefaultDelegate::default();
assert_eq!(delegate.show_description, true);
Source§

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

Source§

fn render(&self, m: &Model<I>, index: usize, item: &I) -> String

Renders an item as a styled string for display in the list.

This method implements the complete rendering pipeline for list items, with special handling for filter highlighting that avoids common ANSI spacing issues.

§Rendering Pipeline
  1. State Detection: Determine if item is selected, dimmed, or has filter matches
  2. Filter Highlighting: Apply character-level highlighting using segment-based approach
  3. Style Application: Apply colors, borders, and padding based on item state
  4. Layout Formatting: Combine title and description if enabled
§Filter Highlighting Implementation

The filter highlighting system is complex due to lipgloss rendering behavior:

§Problem

Lipgloss styles with padding add spaces when applied to individual text segments. If we pass styles with padding directly to apply_character_highlighting, we get:

  • Input: “Nutella” with matches [0] (highlighting ‘N’)
  • Expected: “│ Nutella”
  • Actual: “│ N utella” (extra space between ‘N’ and ‘utella’)
§Solution
  1. Create “base” styles WITHOUT padding/borders for segment highlighting
  2. Apply highlighting using these clean styles via apply_character_highlighting
  3. Manually apply border and padding AFTER highlighting is complete
§Selected vs Unselected Items
  • Selected: Left border (│) + 1 space padding + colored text
  • Unselected: No border + 2 spaces padding + normal text color

This approach ensures seamless text rendering while preserving visual hierarchy.

§Arguments
  • m - The list model containing state and filter information
  • index - The index of this item in the current list view
  • item - The item to render
§Returns

A formatted string with ANSI styling codes. Returns empty string if list width is 0.

§Visual States
  • Normal: Standard appearance with left padding
  • Selected: Highlighted with left border and accent colors
  • Dimmed: Faded appearance when filter input is empty
  • Filtered: Normal or selected appearance with character-level match highlighting
§CRITICAL DEVELOPER NOTES - List Component Bug Fixes

This render method is part of comprehensive fixes for list component issues. READ THIS before modifying anything related to index handling!

§Index Parameter Semantics (VERY IMPORTANT!)

The index parameter represents the original item index in the full items list, NOT a viewport-relative or filtered-relative position. This design is crucial for:

  1. Cursor Highlighting: index == m.cursor comparison works correctly
  2. Filter Highlighting: We can find matches by searching filtered_items
  3. Viewport Scrolling: Highlighting persists across viewport changes
§Fixed Bug Context

Previous issues that were resolved:

  • Cursor highlighting loss: Caused by passing viewport-relative indices
  • Filter input accumulation: Fixed by proper textinput event forwarding
  • Viewport page jumping: Fixed by smooth scrolling implementation
§System Integration

This method works with other fixes in mod.rs:

  • sync_viewport_with_cursor(): Provides smooth viewport scrolling
  • view_items(): Passes original indices instead of viewport-relative ones
  • Filter input handlers: Ensure proper character accumulation

⚠️ WARNING: If you modify index handling here, ensure consistency with view_items()!

Source§

fn height(&self) -> usize

Returns the height in lines that each item occupies.

The height depends on whether descriptions are enabled:

  • With descriptions: Returns the configured height (default 2 lines)
  • Without descriptions: Always returns 1 line

This height is used by the list component for layout calculations, viewport sizing, and scroll positioning.

§Returns

The number of terminal lines each item will occupy when rendered.

Source§

fn spacing(&self) -> usize

Returns the number of blank lines between items.

This spacing is added between each item in the list to improve readability and visual separation. The default spacing is 1 line.

§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.

The default delegate implementation does not require any message handling, so this method always returns None. Override this method in custom delegates that need to respond to keyboard input, timer events, or other application messages.

§Arguments
  • _msg - The message to handle (unused in default implementation)
  • _m - Mutable reference to the list model (unused in default implementation)
§Returns

Always returns None as the default delegate requires no update commands.

Source§

fn short_help(&self) -> Vec<Binding>

Returns key bindings for the short help view. Read more
Source§

fn full_help(&self) -> Vec<Vec<Binding>>

Returns key bindings for the full help view. Read more
Source§

fn on_select(&self, _index: usize, _item: &I) -> Option<Cmd>

Called when an item is selected (e.g., Enter key pressed). Read more
Source§

fn on_remove(&self, _index: usize, _item: &I) -> Option<Cmd>

Called when an item is about to be removed. Read more
Source§

fn can_remove(&self, _index: usize, _item: &I) -> bool

Determines whether an item can be removed. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<S, D, Swp, Dwp, T> AdaptInto<D, Swp, Dwp, T> for S
where 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) -> D
where M: TransformMatrix<T>,

Convert the source color to the destination color using the specified method.
Source§

fn adapt_into(self) -> D

Convert the source color to the destination color using the bradford method by default.
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T, C> ArraysFrom<C> for T
where C: IntoArrays<T>,

Source§

fn arrays_from(colors: C) -> T

Cast a collection of colors into a collection of arrays.
Source§

impl<T, C> ArraysInto<C> for T
where C: FromArrays<T>,

Source§

fn arrays_into(self) -> C

Cast this collection of arrays into a collection of colors.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<WpParam, T, U> Cam16IntoUnclamped<WpParam, T> for U
where T: FromCam16Unclamped<WpParam, U>,

Source§

type Scalar = <T as FromCam16Unclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn cam16_into_unclamped( self, parameters: BakedParameters<WpParam, <U as Cam16IntoUnclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T, C> ComponentsFrom<C> for T
where C: IntoComponents<T>,

Source§

fn components_from(colors: C) -> T

Cast a collection of colors into a collection of color components.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromAngle<T> for T

Source§

fn from_angle(angle: T) -> T

Performs a conversion from angle.
Source§

impl<T, U> FromStimulus<U> for T
where U: IntoStimulus<T>,

Source§

fn from_stimulus(other: U) -> T

Converts other into Self, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> IntoAngle<U> for T
where U: FromAngle<T>,

Source§

fn into_angle(self) -> U

Performs a conversion into T.
Source§

impl<WpParam, T, U> IntoCam16Unclamped<WpParam, T> for U
where T: Cam16FromUnclamped<WpParam, U>,

Source§

type Scalar = <T as Cam16FromUnclamped<WpParam, U>>::Scalar

The number type that’s used in parameters when converting.
Source§

fn into_cam16_unclamped( self, parameters: BakedParameters<WpParam, <U as IntoCam16Unclamped<WpParam, T>>::Scalar>, ) -> T

Converts self into C, using the provided parameters.
Source§

impl<T, U> IntoColor<U> for T
where U: FromColor<T>,

Source§

fn into_color(self) -> U

Convert into T with values clamped to the color defined bounds Read more
Source§

impl<T, U> IntoColorUnclamped<U> for T
where U: FromColorUnclamped<T>,

Source§

fn into_color_unclamped(self) -> U

Convert into T. The resulting color might be invalid in its color space Read more
Source§

impl<T> IntoStimulus<T> for T

Source§

fn into_stimulus(self) -> T

Converts self into T, while performing the appropriate scaling, rounding and clamping.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, C> TryComponentsInto<C> for T
where C: TryFromComponents<T>,

Source§

type Error = <C as TryFromComponents<T>>::Error

The error for when try_into_colors fails to cast.
Source§

fn try_components_into(self) -> Result<C, <T as TryComponentsInto<C>>::Error>

Try to cast this collection of color components into a collection of colors. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T, U> TryIntoColor<U> for T
where U: TryFromColor<T>,

Source§

fn try_into_color(self) -> Result<U, OutOfBounds<U>>

Convert into T, returning ok if the color is inside of its defined range, otherwise an OutOfBounds error is returned which contains the unclamped color. Read more
Source§

impl<C, U> UintsFrom<C> for U
where C: IntoUints<U>,

Source§

fn uints_from(colors: C) -> U

Cast a collection of colors into a collection of unsigned integers.
Source§

impl<C, U> UintsInto<C> for U
where C: FromUints<U>,

Source§

fn uints_into(self) -> C

Cast this collection of unsigned integers into a collection of colors.