use crate::{
AnyElement, Hooks, UsePreviousSize,
prelude::{Fragment, Positioned, Text},
};
use ratatui::{style::Style, text::Span};
use ratatui_kit_macros::{Props, component, element};
#[derive(Debug, Clone, Props, Default)]
pub struct InputProps {
pub input: tui_input::Input,
pub cursor_style: Style,
pub placeholder: String,
pub placeholder_style: Style,
pub style: Style,
pub hide_cursor: bool,
}
#[component]
pub fn Input(props: &InputProps, mut hooks: Hooks) -> impl Into<AnyElement<'static>> {
let size = hooks.use_previous_size();
let input = &props.input;
let input_width = size.width.saturating_sub(1) as usize;
let scroll = if props.hide_cursor || input_width == 0 {
0
} else {
input.visual_scroll(input_width)
};
let text = if input.value().is_empty() {
props.placeholder.clone()
} else {
input.value().to_string()
};
let x = input.visual_cursor().max(scroll) - scroll;
let position = (size.x + x as u16, size.y);
element!(Fragment {
Text(
text:text,
style: if input.value().is_empty() {
props.placeholder_style
}else{
props.style
},
scroll:(0, scroll as u16),
)
if !props.hide_cursor {
Positioned(
x: position.0.min(size.x + size.width.saturating_sub(1)),
y: position.1.min(size.y + size.height),
width: 1u16,
height: 1u16,
){
widget(Span::from(" ").style(props.cursor_style))
}
}
})
}