windjammer_ui/component.rs
1//! Component model and traits
2
3use crate::vdom::VNode;
4
5/// Trait for components
6///
7/// Note: The `render()` method should be implemented as a regular method,
8/// not as part of this trait. The `#[component]` macro will ensure the
9/// struct implements this trait.
10pub trait Component: Send + Sync {
11 /// Initialize the component
12 fn init(&mut self) {}
13
14 /// Update the component with new props
15 fn update(&mut self) {}
16
17 /// Cleanup when component is unmounted
18 fn cleanup(&mut self) {}
19
20 /// Render the component to a virtual DOM node
21 /// This is provided as a trait method for type safety
22 fn render(&self) -> VNode;
23}
24
25/// Props trait for component properties
26pub trait ComponentProps: Clone + Send + Sync {}
27
28/// Implement ComponentProps for unit (components with no props)
29impl ComponentProps for () {}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34 use crate::vdom::VText;
35
36 struct TestComponent;
37
38 impl Component for TestComponent {
39 fn render(&self) -> VNode {
40 VNode::Text(VText {
41 content: "Hello, World!".to_string(),
42 })
43 }
44 }
45
46 #[test]
47 fn test_component_render() {
48 let component = TestComponent;
49 let vnode = component.render();
50 assert!(matches!(vnode, VNode::Text(_)));
51 }
52}