web_component/web_component/
mod.rs

1use crate::prelude::*;
2
3mod properties;
4pub use properties::*;
5
6pub trait WebComponent: Sized + FromProperties<Self::Properties> {
7    type Properties: Properties + PartialEq + std::fmt::Debug;
8
9    fn instance(properties: &Self::Properties) -> Signal<Self> {
10        // let mut component = use_signal(|| {
11        //     let mut state = state.clone();
12        //     state.initialize();
13        //     state
14        // });
15        // use_effect(move || {
16        //     component.write().on_mount();
17        //     let id = component.write().id().clone();
18        //     if let Some(id) = id {
19        //         if let Some(window) = web_sys::window() {
20        //             if let Some(document) = window.document() {
21        //                 if let Some(element) = document.get_element_by_id(&id) {
22        //                     component.write().on_mount_with_element(element);
23        //                 }
24        //             }
25        //         }
26        //     }
27        // });
28        // if *component.read() != state {
29        //     component.write().update(state);
30        // }
31        // component
32        let input_properties = properties;
33        let mut properties = use_signal(|| input_properties.clone());
34        let mut component = use_signal(|| Self::from_properties(input_properties.clone()));
35        use_effect(capture!(input_properties => move || {
36            if properties.read().to_owned() != input_properties {
37                *properties.write() = input_properties.clone();
38                *component.write() = Self::from_properties(input_properties.clone());
39            }
40        }));
41        component
42    }
43    fn initialize(&mut self) {
44
45    }
46
47    fn id(&self) -> Option<String> {
48        None
49    }
50
51    fn on_mount(&mut self) {
52    }
53
54    fn on_mount_with_element(&mut self, _element: web_sys::Element) {
55    }
56
57    fn update(&mut self, state: Self) {
58        *self = state;
59    }
60    
61    fn render(component: Signal<Self>) -> Element;
62}
63
64#[macro_export]
65macro_rules! expose_component {
66    ($component:ident as $name:ident) => {
67        #[component]
68        pub fn $name(props: <$component as WebComponent>::Properties) -> Element {
69            let component = $component::instance(&props);
70            WebComponent::render(component)
71        }
72    };
73}