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