diff --git a/src/client/components/form.rs b/src/client/components/form.rs index 0c568ca..30a0ba9 100644 --- a/src/client/components/form.rs +++ b/src/client/components/form.rs @@ -1,7 +1,7 @@ // src/client/components/form.rs use ratatui::{ widgets::{Paragraph, Block, Borders}, - layout::{Layout, Constraint, Direction, Rect, Margin, Position}, + layout::{Layout, Constraint, Direction, Rect, Margin, Alignment}, style::Style, text::{Line, Span}, Frame, @@ -16,14 +16,13 @@ pub fn render_form( inputs: &[&String], theme: &Theme, ) { - // Create a block for the Adresar card + // Create Adresar card let adresar_card = Block::default() .borders(Borders::ALL) .border_style(Style::default().fg(theme.border)) .title(" Adresar ") .style(Style::default().bg(theme.bg).fg(theme.fg)); - // Render the card first f.render_widget(adresar_card, area); // Define the inner area for the form (inside the card) @@ -32,56 +31,71 @@ pub fn render_form( vertical: 1, }); - // Split the inner area into two columns: labels and inputs + // Split into label column and input column let columns = Layout::default() .direction(Direction::Horizontal) .constraints([Constraint::Percentage(30), Constraint::Percentage(70)]) .split(inner_area); - // Create a bordered block for the input area - let input_block = Block::default() + // Create compact input container + let input_container = Block::default() .borders(Borders::ALL) - .border_style(Style::default().fg(theme.accent)); + .border_style(Style::default().fg(theme.accent)) + .style(Style::default().bg(theme.bg)); - // Render the labels on the left - let label_area = columns[0]; + // Center the input box vertically + let vertical_center = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Min(1), + Constraint::Length(fields.len() as u16 + 2), // +2 for borders + Constraint::Min(1), + ]) + .split(columns[1]); + + // Render the input container + f.render_widget(&input_container, vertical_center[1]); + + // Input area inside borders + let input_area = input_container.inner(vertical_center[1]); + let input_rows = Layout::default() + .direction(Direction::Vertical) + .constraints(vec![Constraint::Length(1); fields.len()]) + .split(input_area); + + // Render labels close to the border for (i, field) in fields.iter().enumerate() { let label = Paragraph::new(Line::from(Span::styled( - field.to_string(), + format!("{}:", field), Style::default().fg(theme.fg), ))); f.render_widget(label, Rect { - x: label_area.x, - y: label_area.y + i as u16, - width: label_area.width, + x: columns[0].x, + y: vertical_center[1].y + 1 + i as u16, // Align with input rows + width: columns[0].width, height: 1, }); } - // Render the inputs inside the bordered block - let input_area = input_block.inner(columns[1]); - f.render_widget(input_block, columns[1]); - + // Render inputs with left-aligned text and free cursor movement for (i, input) in inputs.iter().enumerate() { - let input_paragraph = Paragraph::new(input.as_str()) - .style(if i == *current_field { + let is_active = i == *current_field; + + let input_display = Paragraph::new(input.as_str()) + .alignment(Alignment::Left) + .style(if is_active { Style::default().fg(theme.highlight) } else { Style::default().fg(theme.fg) }); - f.render_widget(input_paragraph, Rect { - x: input_area.x, - y: input_area.y + i as u16, - width: input_area.width, - height: 1, - }); + f.render_widget(input_display, input_rows[i]); - // Render the cursor in the active field - if i == *current_field { - let cursor_x = input_area.x + input.len() as u16; - let cursor_y = input_area.y + i as u16; - f.set_cursor_position(Position::new(cursor_x, cursor_y)); + // Position cursor at the correct position in the active field + if is_active { + let cursor_x = input_rows[i].x + input.len() as u16; + let cursor_y = input_rows[i].y; + f.set_cursor(cursor_x, cursor_y); } } }