ratatui_kit/element/
element.rs

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