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}