multiverse/widgets/
popup_input.rs1use crossterm::event::KeyEvent;
2use ratatui::{
3 buffer::Buffer,
4 layout::{Constraint, Flex, Layout, Rect},
5 style::{Stylize, palette::tailwind},
6 widgets::{Block, Borders, Clear, Widget},
7};
8use tui_textarea::TextArea;
9
10#[derive(Default, Clone)]
11pub(crate) struct PopupInput {
12 textarea: TextArea<'static>,
14
15 title: String,
17
18 placeholder_text: String,
20
21 width_constraint: Constraint,
23
24 height_constraint: Constraint,
26}
27
28impl PopupInput {
29 pub fn new<T: Into<String>>(title: T, placeholder_text: T) -> Self {
31 let mut ret = Self {
32 textarea: TextArea::default(),
33 title: title.into(),
34 placeholder_text: placeholder_text.into(),
35 width_constraint: Constraint::Percentage(40),
36 height_constraint: Constraint::Length(3),
37 };
38
39 ret.textarea.set_placeholder_text(ret.placeholder_text.clone());
41
42 let input_block =
44 Block::new().borders(Borders::ALL).bg(tailwind::BLUE.c400).title(ret.title.clone());
45
46 ret.textarea.set_block(input_block);
48
49 ret
50 }
51
52 pub fn width_constraint(&mut self, value: Constraint) -> Self {
54 self.width_constraint = value;
55 self.clone()
56 }
57
58 pub fn height_constraint(&mut self, value: Constraint) -> Self {
60 self.height_constraint = value;
61 self.clone()
62 }
63
64 pub fn handle_key_press(&mut self, key: KeyEvent) {
66 self.textarea.input(key);
67 }
68
69 pub fn get_input(&self) -> String {
71 self.textarea.lines().join("\n")
72 }
73}
74
75impl Widget for &mut PopupInput {
76 fn render(self, area: Rect, buf: &mut Buffer) {
77 let vertical = Layout::vertical([self.height_constraint]).flex(Flex::Center);
78 let horizontal = Layout::horizontal([self.width_constraint]).flex(Flex::Center);
79 let [area] = vertical.areas(area);
80 let [area] = horizontal.areas(area);
81 Clear.render(area, buf);
82
83 self.textarea.render(area, buf);
84 }
85}