From f4d234089fcb5fe0e29eb72768abb0055a37f3a0 Mon Sep 17 00:00:00 2001 From: filipriec Date: Sat, 12 Apr 2025 15:52:12 +0200 Subject: [PATCH] much better, still not it --- client/src/components/common/autocomplete.rs | 53 +++++++++++--------- client/src/components/handlers/canvas.rs | 11 ++-- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/client/src/components/common/autocomplete.rs b/client/src/components/common/autocomplete.rs index db618b1..6e0b1f8 100644 --- a/client/src/components/common/autocomplete.rs +++ b/client/src/components/common/autocomplete.rs @@ -2,52 +2,57 @@ use crate::config::colors::themes::Theme; use ratatui::{ - buffer::Buffer, layout::Rect, style::{Color, Modifier, Style}, - widgets::{List, ListItem, ListState, StatefulWidget, Widget}, + widgets::{Block, List, ListItem, ListState}, Frame, }; -/// Renders a bordered list dropdown for autocomplete suggestions. +/// Renders an opaque dropdown list for autocomplete suggestions. pub fn render_autocomplete_dropdown( f: &mut Frame, - area: Rect, // The area where the dropdown should be rendered + area: Rect, theme: &Theme, suggestions: &[String], selected_index: Option, ) { if suggestions.is_empty() { - return; // Don't render if no suggestions + return; } - // --- Render Background --- - struct GrayBackground; - impl Widget for GrayBackground { - fn render(self, area: Rect, buf: &mut Buffer) { - buf.set_style(area, Style::default().bg(Color::DarkGray)); // Set background - } - } - f.render_widget(GrayBackground, area); - // --- Render Suggestions List (without block/border) --- + // 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); + + // Create list items, ensuring each has a defined background let items: Vec = suggestions .iter() - .map(|s| ListItem::new(s.as_str()).style(Style::default().fg(theme.fg))) // Set default text color + .enumerate() + .map(|(i, s)| { + let is_selected = selected_index == Some(i); + ListItem::new(s.as_str()).style(if is_selected { + // Style for selected item (highlight background) + Style::default() + .fg(theme.bg) // Text color on highlight + .bg(theme.highlight) // Highlight background + .add_modifier(Modifier::BOLD) + } else { + // Style for non-selected items (matching background block) + Style::default() + .fg(theme.fg) // Text color on gray + .bg(Color::DarkGray) // Explicit gray background + }) + }) .collect(); - let list = List::new(items) - .highlight_style( - Style::default() - .add_modifier(Modifier::BOLD) - .bg(theme.highlight) - .fg(theme.bg), - ) - .highlight_symbol("> "); // Symbol for selected item + // Create the list widget (without its own block) + let list = List::new(items); - // Create a state for the list to handle selection highlighting + // State for managing selection highlight (still needed for logic) let mut list_state = ListState::default(); list_state.select(selected_index); + // Render the list statefully *over* the background block f.render_stateful_widget(list, area, &mut list_state); } diff --git a/client/src/components/handlers/canvas.rs b/client/src/components/handlers/canvas.rs index 9488ad3..8b52e46 100644 --- a/client/src/components/handlers/canvas.rs +++ b/client/src/components/handlers/canvas.rs @@ -100,12 +100,15 @@ pub fn render_canvas( if let Some(input_rect) = active_field_input_rect { let selected_index = form_state.get_selected_suggestion_index(); - // Calculate dropdown area below the active input field - let dropdown_height = (suggestions.len() as u16).min(5) + 2; // Max 5 suggestions + border + // --- Calculate Compact Dropdown Size --- + let max_suggestion_width = suggestions.iter().map(|s| s.len()).max().unwrap_or(0) as u16; + let dropdown_width = max_suggestion_width.max(10); // Use longest suggestion width, min 10 + let dropdown_height = (suggestions.len() as u16).min(5); // Height matches suggestion count, max 5 + // --- End Size Calculation --- let dropdown_area = Rect { x: input_rect.x, - y: input_rect.y + 1, // Position below the input line - width: input_rect.width.max(20), // Ensure minimum width + y: input_rect.y + 1, + width: dropdown_width, height: dropdown_height, };