mecomp_tui/ui/components/content_view/views/
none.rs1use ratatui::{layout::Alignment, style::Style, text::Line, widgets::Block};
4
5use crate::ui::{
6 colors::{BORDER_FOCUSED, BORDER_UNFOCUSED, TEXT_NORMAL},
7 components::{Component, ComponentRender, RenderProps},
8 AppState,
9};
10
11#[allow(clippy::module_name_repetitions)]
12pub struct NoneView;
13
14impl Component for NoneView {
15 fn new(
16 _state: &AppState,
17 _action_tx: tokio::sync::mpsc::UnboundedSender<crate::state::action::Action>,
18 ) -> Self
19 where
20 Self: Sized,
21 {
22 Self
23 }
24
25 fn move_with_state(self, _state: &AppState) -> Self
26 where
27 Self: Sized,
28 {
29 self
30 }
31
32 fn name(&self) -> &'static str {
33 "None"
34 }
35
36 fn handle_key_event(&mut self, _key: crossterm::event::KeyEvent) {
37 }
39
40 fn handle_mouse_event(&mut self, _: crossterm::event::MouseEvent, _: ratatui::layout::Rect) {
41 }
43}
44
45impl ComponentRender<RenderProps> for NoneView {
46 fn render_border(&self, frame: &mut ratatui::Frame, props: RenderProps) -> RenderProps {
47 let border_style = if props.is_focused {
48 Style::default().fg(BORDER_FOCUSED.into())
49 } else {
50 Style::default().fg(BORDER_UNFOCUSED.into())
51 };
52
53 let block = Block::bordered().border_style(border_style);
54 let area = block.inner(props.area);
55 frame.render_widget(block, props.area);
56
57 RenderProps { area, ..props }
58 }
59
60 fn render_content(&self, frame: &mut ratatui::Frame, props: RenderProps) {
61 let text = "No active view";
62
63 frame.render_widget(
64 Line::from(text)
65 .style(Style::default().fg(TEXT_NORMAL.into()))
66 .alignment(Alignment::Center),
67 props.area,
68 );
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use crate::{
76 test_utils::{assert_buffer_eq, setup_test_terminal, state_with_everything},
77 ui::components::content_view::ActiveView,
78 };
79 use anyhow::Result;
80 use ratatui::buffer::Buffer;
81
82 #[test]
83 fn test_render() -> Result<()> {
84 let (tx, _) = tokio::sync::mpsc::unbounded_channel();
85 let view = NoneView::new(&AppState::default(), tx).move_with_state(&AppState {
86 active_view: ActiveView::None,
87 ..state_with_everything()
88 });
89
90 let (mut terminal, area) = setup_test_terminal(16, 3);
91 let props = RenderProps {
92 area,
93 is_focused: true,
94 };
95 let buffer = terminal
96 .draw(|frame| view.render(frame, props))
97 .unwrap()
98 .buffer
99 .clone();
100 #[rustfmt::skip]
101 let expected = Buffer::with_lines([
102 "┌──────────────┐",
103 "│No active view│",
104 "└──────────────┘",
105 ]);
106
107 assert_buffer_eq(&buffer, &expected);
108
109 Ok(())
110 }
111}