From b4053a7b947aaa24742071f69648bef04dddfdaa Mon Sep 17 00:00:00 2001 From: filipriec Date: Sat, 12 Apr 2025 17:34:17 +0200 Subject: [PATCH] working perfectly well --- client/src/components/common/autocomplete.rs | 34 ++++++++++++++++++-- client/src/components/handlers/canvas.rs | 6 +++- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/client/src/components/common/autocomplete.rs b/client/src/components/common/autocomplete.rs index 6e0b1f8..1c2cd2f 100644 --- a/client/src/components/common/autocomplete.rs +++ b/client/src/components/common/autocomplete.rs @@ -11,7 +11,8 @@ use ratatui::{ /// Renders an opaque dropdown list for autocomplete suggestions. pub fn render_autocomplete_dropdown( f: &mut Frame, - area: Rect, + input_rect: Rect, + frame_area: Rect, theme: &Theme, suggestions: &[String], selected_index: Option, @@ -19,10 +20,37 @@ pub fn render_autocomplete_dropdown( if suggestions.is_empty() { return; } + // --- Calculate Dropdown Size & Position --- + let max_suggestion_width = suggestions.iter().map(|s| s.len()).max().unwrap_or(0) as u16; + // Ensure dropdown is at least as wide as the input field, or the longest suggestion, min 10 + let dropdown_width = max_suggestion_width.max(input_rect.width).max(10); + let dropdown_height = (suggestions.len() as u16).min(5); // Max 5 suggestions visible + + let mut dropdown_area = Rect { + x: input_rect.x, // Align horizontally with input + y: input_rect.y + 1, // Position directly below input + width: dropdown_width, + height: dropdown_height, + }; + + // --- Clamping Logic (prevent rendering off-screen) --- + // Clamp vertically (if it goes below the frame) + if dropdown_area.bottom() > frame_area.height { + dropdown_area.y = input_rect.y.saturating_sub(dropdown_height); // Try rendering above + } + // Clamp horizontally (if it goes past the right edge) + if dropdown_area.right() > frame_area.width { + dropdown_area.x = frame_area.width.saturating_sub(dropdown_width); + } + // Ensure x is not negative (if clamping pushes it left) + dropdown_area.x = dropdown_area.x.max(0); + // Ensure y is not negative (if clamping pushes it up) + dropdown_area.y = dropdown_area.y.max(0); + // --- End Clamping --- // Render a solid background block first to ensure opacity let background_block = Block::default().style(Style::default().bg(Color::DarkGray)); - f.render_widget(background_block, area); + f.render_widget(background_block, dropdown_area); // Create list items, ensuring each has a defined background let items: Vec = suggestions @@ -53,6 +81,6 @@ pub fn render_autocomplete_dropdown( list_state.select(selected_index); // Render the list statefully *over* the background block - f.render_stateful_widget(list, area, &mut list_state); + f.render_stateful_widget(list, dropdown_area, &mut list_state); } diff --git a/client/src/components/handlers/canvas.rs b/client/src/components/handlers/canvas.rs index de666d7..ca9c5e5 100644 --- a/client/src/components/handlers/canvas.rs +++ b/client/src/components/handlers/canvas.rs @@ -98,6 +98,10 @@ pub fn render_canvas( // --- Render Autocomplete Dropdown (if applicable) --- if let Some(suggestions) = form_state.get_suggestions() { let selected = form_state.get_selected_suggestion_index(); - render_autocomplete_dropdown(f, area, theme, suggestions, selected); + if !suggestions.is_empty() { + if let Some(input_rect) = active_field_input_rect { + autocomplete::render_autocomplete_dropdown(f, input_rect, f.size(), theme, suggestions, selected); + } + } } }