ratatui_kit/element/
mod.rs1use crate::{
2 AnyProps, Component, ComponentHelper, ComponentHelperExt, CrossTerminal, Terminal,
3 tree::{render, render_loop},
4};
5use std::io;
6mod key;
7pub use key::ElementKey;
8mod any_element;
9pub use any_element::AnyElement;
10mod element_ext;
11pub use element_ext::ElementExt;
12mod extend_with_elements;
13pub use extend_with_elements::{ExtendWithElements, extend_with_elements};
14
15pub trait ElementType {
16 type Props<'a>
17 where
18 Self: 'a;
19}
20
21#[derive(Clone)]
22pub struct Element<'a, T: ElementType + 'a> {
23 pub key: ElementKey,
24 pub props: T::Props<'a>,
25}
26
27impl<'a, T> Element<'a, T>
28where
29 T: Component + 'a,
30{
31 pub fn into_any(self) -> AnyElement<'a> {
32 self.into()
33 }
34}
35
36impl<'a, T> ElementExt for Element<'a, T>
37where
38 T: Component,
39{
40 fn key(&self) -> &ElementKey {
41 &self.key
42 }
43
44 fn helper(&self) -> Box<dyn ComponentHelperExt> {
45 ComponentHelper::<T>::boxed()
46 }
47
48 fn props_mut(&mut self) -> AnyProps {
49 AnyProps::borrowed(&mut self.props)
50 }
51
52 fn render(&mut self) -> io::Result<()> {
53 let terminal = Terminal::new(CrossTerminal::new(false)?);
54 render(self, terminal)?;
55 Ok(())
56 }
57
58 async fn render_loop(&mut self) -> io::Result<()> {
59 let terminal = Terminal::new(CrossTerminal::new(false)?);
60 render_loop(self, terminal).await?;
61 Ok(())
62 }
63
64 async fn fullscreen(&mut self) -> io::Result<()> {
65 let terminal = Terminal::new(CrossTerminal::new(true)?);
66 render_loop(self, terminal).await?;
67 Ok(())
68 }
69}
70
71impl<'a, T> ElementExt for &mut Element<'a, T>
72where
73 T: Component,
74{
75 fn key(&self) -> &ElementKey {
76 &self.key
77 }
78
79 fn helper(&self) -> Box<dyn ComponentHelperExt> {
80 ComponentHelper::<T>::boxed()
81 }
82
83 fn props_mut(&mut self) -> AnyProps {
84 AnyProps::borrowed(&mut self.props)
85 }
86
87 fn render(&mut self) -> io::Result<()> {
88 let terminal = Terminal::new(CrossTerminal::new(false)?);
89 render(&mut **self, terminal)?;
90 Ok(())
91 }
92
93 async fn render_loop(&mut self) -> io::Result<()> {
94 let terminal = Terminal::new(CrossTerminal::new(false)?);
95 render_loop(&mut **self, terminal).await?;
96 Ok(())
97 }
98
99 async fn fullscreen(&mut self) -> io::Result<()> {
100 let terminal = Terminal::new(CrossTerminal::new(true)?);
101 render_loop(&mut **self, terminal).await?;
102 Ok(())
103 }
104}