refactor: 🔨 fix linting issues
This commit is contained in:
parent
97457af448
commit
0c765a608b
77
examples/widget_text_area.rs
Normal file
77
examples/widget_text_area.rs
Normal file
@ -0,0 +1,77 @@
|
||||
use {
|
||||
lool::tui::{
|
||||
ratatui::{
|
||||
backend::CrosstermBackend,
|
||||
crossterm::{
|
||||
event::{self},
|
||||
execute,
|
||||
terminal::{
|
||||
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen,
|
||||
},
|
||||
},
|
||||
layout::{Constraint, Direction, Layout},
|
||||
Terminal,
|
||||
},
|
||||
widgets::textarea::{Input, Key, TextArea},
|
||||
},
|
||||
ratatui::widgets::{Block, BorderType, Borders, Padding, Paragraph},
|
||||
std::{cmp, io},
|
||||
};
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let stdout = io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
|
||||
enable_raw_mode()?;
|
||||
execute!(stdout, EnterAlternateScreen)?;
|
||||
let backend = CrosstermBackend::new(stdout);
|
||||
let mut term = Terminal::new(backend)?;
|
||||
|
||||
let mut textarea = TextArea::default().with_block(
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_type(BorderType::Rounded)
|
||||
.title(" Your name ")
|
||||
.padding(Padding::horizontal(1)),
|
||||
);
|
||||
|
||||
loop {
|
||||
term.draw(|f| {
|
||||
const MIN_HEIGHT: usize = 1;
|
||||
let height = cmp::max(textarea.lines().len(), MIN_HEIGHT) as u16 + 2;
|
||||
let layout = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints([Constraint::Length(height), Constraint::Min(1)])
|
||||
.split(f.area());
|
||||
|
||||
// Render the textarea
|
||||
f.render_widget(&textarea, layout[0]);
|
||||
f.render_widget(Paragraph::new("Press <Esc> to exit"), layout[1]);
|
||||
})?;
|
||||
match event::read()?.into() {
|
||||
Input { key: Key::Esc, .. }
|
||||
| Input {
|
||||
key: Key::Char('c'),
|
||||
shift: false,
|
||||
ctrl: true,
|
||||
alt: false,
|
||||
}
|
||||
| Input {
|
||||
key: Key::Enter,
|
||||
ctrl: false,
|
||||
shift: false,
|
||||
alt: false,
|
||||
} => break,
|
||||
input => {
|
||||
textarea.input(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
disable_raw_mode()?;
|
||||
execute!(term.backend_mut(), LeaveAlternateScreen)?;
|
||||
term.show_cursor()?;
|
||||
|
||||
println!("Lines: {:?}", textarea.lines());
|
||||
Ok(())
|
||||
}
|
||||
@ -261,6 +261,7 @@ pub trait Component: Downcast {
|
||||
///
|
||||
/// # Returns
|
||||
/// * `Option<&Box<dyn Component>>` - A reference to the child component or none.
|
||||
#[allow(clippy::borrowed_box)]
|
||||
fn child(&mut self, name: &str) -> Option<&Box<dyn Component>> {
|
||||
if let Some(children) = self.get_children() {
|
||||
children.get(name)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use {
|
||||
super::util::{find_word_start_backward, find_word_start_forward},
|
||||
crate::tui::widgets::textarea::textarea::widget::Viewport,
|
||||
crate::tui::widgets::textarea::core::widget::Viewport,
|
||||
std::cmp,
|
||||
};
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
|
||||
/// Backend-agnostic key input kind.
|
||||
///
|
||||
/// This type is marked as `#[non_exhaustive]` since more keys may be supported in the future.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Hash, Eq, Default)]
|
||||
pub enum Key {
|
||||
/// Normal letter key input
|
||||
Char(char),
|
||||
@ -38,15 +38,10 @@ pub enum Key {
|
||||
/// Paste key. This key is supported by termwiz only
|
||||
Paste,
|
||||
/// An invalid key input (this key is always ignored by [`TextArea`](crate::TextArea))
|
||||
#[default]
|
||||
Null,
|
||||
}
|
||||
|
||||
impl Default for Key {
|
||||
fn default() -> Self {
|
||||
Key::Null
|
||||
}
|
||||
}
|
||||
|
||||
/// Backend-agnostic key input type.
|
||||
///
|
||||
/// When `crossterm`, `termion`, `termwiz` features are enabled, converting respective key input types into this
|
||||
@ -104,7 +99,7 @@ impl Input {
|
||||
ctrl: false,
|
||||
alt: false,
|
||||
..
|
||||
} => Some(c.clone()),
|
||||
} => Some(*c),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -117,30 +112,27 @@ impl Input {
|
||||
/// - Char is \n or \r
|
||||
#[inline]
|
||||
pub fn is_newline_except_enter(&self) -> bool {
|
||||
match self {
|
||||
matches!(
|
||||
self,
|
||||
Input {
|
||||
key: Key::Char('\n' | '\r'),
|
||||
ctrl: false,
|
||||
alt: false,
|
||||
..
|
||||
}
|
||||
| Input {
|
||||
} | Input {
|
||||
key: Key::Enter,
|
||||
ctrl: true,
|
||||
..
|
||||
}
|
||||
| Input {
|
||||
} | Input {
|
||||
key: Key::Enter,
|
||||
alt: true,
|
||||
..
|
||||
}
|
||||
| Input {
|
||||
} | Input {
|
||||
key: Key::Enter,
|
||||
shift: true,
|
||||
..
|
||||
} => true,
|
||||
_ => false,
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input represents a new line (including Enter key).
|
||||
@ -170,67 +162,67 @@ impl Input {
|
||||
/// Returns `true` if the Input is a Tab
|
||||
#[inline]
|
||||
pub fn is_tab(&self) -> bool {
|
||||
return self.key == Key::Tab && !self.ctrl && !self.alt;
|
||||
self.key == Key::Tab && !self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is Backspace
|
||||
#[inline]
|
||||
pub fn is_backspace(&self) -> bool {
|
||||
return self.key == Key::Backspace && !self.ctrl && !self.alt;
|
||||
self.key == Key::Backspace && !self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is Delete
|
||||
#[inline]
|
||||
pub fn is_delete(&self) -> bool {
|
||||
return self.key == Key::Delete && !self.ctrl && !self.alt;
|
||||
self.key == Key::Delete && !self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is key down arrow
|
||||
#[inline]
|
||||
pub fn is_down(&self) -> bool {
|
||||
return self.key == Key::Down && !self.ctrl && !self.alt;
|
||||
self.key == Key::Down && !self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is key up arrow
|
||||
#[inline]
|
||||
pub fn is_up(&self) -> bool {
|
||||
return self.key == Key::Up && !self.ctrl && !self.alt;
|
||||
self.key == Key::Up && !self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is key left arrow
|
||||
#[inline]
|
||||
pub fn is_left(&self) -> bool {
|
||||
return self.key == Key::Left && !self.ctrl && !self.alt;
|
||||
self.key == Key::Left && !self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is key right arrow
|
||||
#[inline]
|
||||
pub fn is_right(&self) -> bool {
|
||||
return self.key == Key::Right && !self.ctrl && !self.alt;
|
||||
self.key == Key::Right && !self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is key Home
|
||||
#[inline]
|
||||
pub fn is_home(&self) -> bool {
|
||||
return self.key == Key::Home;
|
||||
self.key == Key::Home
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is key End
|
||||
#[inline]
|
||||
pub fn is_end(&self) -> bool {
|
||||
return self.key == Key::End;
|
||||
self.key == Key::End
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is ctrl+left
|
||||
#[inline]
|
||||
pub fn is_ctrl_left(&self) -> bool {
|
||||
return self.key == Key::Left && self.ctrl && !self.alt;
|
||||
self.key == Key::Left && self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns `true` if the Input is ctrl+right
|
||||
#[inline]
|
||||
pub fn is_ctrl_right(&self) -> bool {
|
||||
return self.key == Key::Right && self.ctrl && !self.alt;
|
||||
self.key == Key::Right && self.ctrl && !self.alt
|
||||
}
|
||||
|
||||
/// Returns a string representing the kind of key input.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::tui::widgets::textarea::textarea::widget::Viewport;
|
||||
use crate::tui::widgets::textarea::core::widget::Viewport;
|
||||
|
||||
/// Specify how to scroll the textarea.
|
||||
///
|
||||
|
||||
@ -59,5 +59,5 @@ pub fn find_word_start_backward(line: &str, start_col: usize) -> Option<usize> {
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
(cur != CharKind::Space).then(|| 0)
|
||||
(cur != CharKind::Space).then_some(0)
|
||||
}
|
||||
|
||||
@ -512,5 +512,3 @@ impl<'a> TextArea<'a> {
|
||||
hl.into_spans()
|
||||
}
|
||||
}
|
||||
|
||||
// Builder-Pattern methods
|
||||
@ -7,8 +7,10 @@ pub enum ValidationResult {
|
||||
Invalid(Vec<String>),
|
||||
}
|
||||
|
||||
type ValidatorFnType = Arc<dyn Fn(&str) -> Result<(), String> + Send + Sync>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ValidatorFn(Arc<dyn Fn(&str) -> Result<(), String> + Send + Sync>);
|
||||
pub struct ValidatorFn(ValidatorFnType);
|
||||
|
||||
impl ValidatorFn {
|
||||
pub fn new<F>(f: F) -> Self
|
||||
@ -1,6 +1,6 @@
|
||||
pub fn required_validator(input: &str) -> Result<(), String> {
|
||||
if input.is_empty() {
|
||||
Err(format!("This field is required"))
|
||||
Err("This field is required".to_string())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
@ -6,11 +6,11 @@ pub(super) mod behaviour {
|
||||
pub(super) mod util;
|
||||
}
|
||||
|
||||
mod textarea;
|
||||
mod core;
|
||||
|
||||
pub use {
|
||||
behaviour::input::{Input, Key},
|
||||
textarea::{
|
||||
core::{
|
||||
validation::{validators, ValidationResult},
|
||||
TextArea,
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user