bubbletea_widgets/list/
api.rs

1//! Enhanced API methods for list filter state management.
2//!
3//! This module provides convenient methods for programmatic filter state management,
4//! eliminating the need for workarounds or manual state parsing. These methods
5//! complement the existing keyboard-driven interface with clean programmatic access.
6
7use super::types::{FilterState, FilterStateInfo, Item};
8use super::Model;
9use bubbletea_rs::Cmd;
10
11impl<I: Item + Send + Sync + 'static> Model<I> {
12    /// Returns true if filtering is currently active in any form.
13    ///
14    /// This method provides a simple way to check if the list is in any filtering
15    /// state (either actively typing a filter or has an applied filter). It's useful
16    /// for applications that need to conditionally show UI elements or change behavior
17    /// based on filtering status.
18    ///
19    /// # Returns
20    ///
21    /// - `true` if in `Filtering` or `FilterApplied` state
22    /// - `false` if in `Unfiltered` state
23    ///
24    /// # Examples
25    ///
26    /// ```
27    /// use bubbletea_widgets::list::{Model, DefaultDelegate, DefaultItem, FilterState};
28    ///
29    /// let items = vec![DefaultItem::new("Apple", "Red fruit")];
30    /// let mut list = Model::new(items, DefaultDelegate::new(), 80, 24);
31    ///
32    /// assert!(!list.is_filtering()); // Initially not filtering
33    ///
34    /// // Simulate applying a filter (would normally be done through user input)
35    /// list.set_filter_text("app");
36    /// // In a real application, filter would be applied through the update() method
37    /// assert!(!list.is_filtering()); // Still not filtering until state changes
38    /// ```
39    pub fn is_filtering(&self) -> bool {
40        matches!(
41            self.filter_state,
42            FilterState::Filtering | FilterState::FilterApplied
43        )
44    }
45
46    /// Forces complete filter clearing in a single operation.
47    ///
48    /// This method provides a programmatic way to completely clear any active filter,
49    /// equivalent to the user pressing the clear filter key binding. It's useful for
50    /// applications that need to reset the list state or implement custom clear
51    /// functionality.
52    ///
53    /// # Returns
54    ///
55    /// Returns `None` as no follow-up commands are needed for the clear operation.
56    ///
57    /// # Effects
58    ///
59    /// - Clears the filter input text
60    /// - Sets state to `Unfiltered`
61    /// - Clears filtered items list
62    /// - Resets cursor to position 0
63    /// - Updates pagination
64    ///
65    /// # Examples
66    ///
67    /// ```
68    /// use bubbletea_widgets::list::{Model, DefaultDelegate, DefaultItem};
69    ///
70    /// let items = vec![DefaultItem::new("Apple", "Red fruit")];
71    /// let mut list = Model::new(items, DefaultDelegate::new(), 80, 24);
72    ///
73    /// // Apply a filter (this would normally be done through user interaction)
74    /// list.set_filter_text("app");
75    ///
76    /// // Clear it programmatically
77    /// let cmd = list.clear_filter();
78    /// assert!(cmd.is_none()); // Returns None
79    /// assert!(!list.is_filtering()); // No longer filtering
80    /// ```
81    pub fn clear_filter(&mut self) -> Option<Cmd> {
82        self.filter_input.set_value("");
83        self.filter_state = FilterState::Unfiltered;
84        self.filtered_items.clear();
85        self.cursor = 0;
86        self.update_pagination();
87        None
88    }
89
90    /// Returns detailed information about the current filter state.
91    ///
92    /// This method provides comprehensive information about filtering without requiring
93    /// direct access to internal fields. It's particularly useful for applications that
94    /// need to display filter status information or make decisions based on detailed
95    /// filter state.
96    ///
97    /// # Returns
98    ///
99    /// A `FilterStateInfo` struct containing:
100    /// - Current filter state enum
101    /// - Filter query text
102    /// - Number of matching items
103    /// - Whether filtering is active
104    /// - Whether currently in clearing state
105    ///
106    /// # Examples
107    ///
108    /// ```
109    /// use bubbletea_widgets::list::{Model, DefaultDelegate, DefaultItem, FilterState};
110    ///
111    /// let items = vec![
112    ///     DefaultItem::new("Apple", "Red fruit"),
113    ///     DefaultItem::new("Banana", "Yellow fruit"),
114    /// ];
115    /// let mut list = Model::new(items, DefaultDelegate::new(), 80, 24);
116    ///
117    /// // Check initial state
118    /// let info = list.filter_state_info();
119    /// assert_eq!(info.state, FilterState::Unfiltered);
120    /// assert_eq!(info.query, "");
121    /// assert_eq!(info.match_count, 2); // All items visible
122    /// assert!(!info.is_filtering);
123    /// assert!(!info.is_clearing);
124    ///
125    /// // Set filter text (would be applied through user interaction)
126    /// list.set_filter_text("app");
127    /// let info = list.filter_state_info();
128    /// assert_eq!(info.query, "app"); // Query is set
129    /// ```
130    pub fn filter_state_info(&self) -> FilterStateInfo {
131        FilterStateInfo {
132            state: self.filter_state.clone(),
133            query: self.filter_input.value(),
134            match_count: self.len(),
135            is_filtering: self.is_filtering(),
136            is_clearing: false, // This would be true during intermediate clearing states
137        }
138    }
139}