Clone in a terminal:
Commit d955433
Johan Mattsson - 2026-10-28T15:41:17+00:00
d955433914b23af35d23706cba989690286b3b22johan.mattsson.m@gmail.com

Documentation

Changed files (2)

Diff

diff --git a/README.md b/README.mdnew file mode 100644index 0000000..9a869bd--- /dev/null+++ b/README.md@@ -0,0 +1,102 @@+# Kaja Web Component Example++A simple example of a custom HTML component using Rust and Kaja Web. Similar in functionality to +other web component libraries but small and fast.++## Component++```rust+use kaja_web::prelude::*;++#[component("main-component")]+struct Main {+    #[attribute]+    test: bool,+}+```++The `#[component]` macro defines a custom HTML element, named `main-component` in this example. +The `#[attribute]` macro associates the `test` field with an HTML attribute. Attributes can be+updated with main-component.set_attribute("something", "somethingelse");. Or used in html like this:+`<main-component test="true"><main-component>`++## Implementation++The macro generates a new empty impl called MainComponent, different from Main but with access to +the same functionality.++```rust+use kaja_web::prelude::*;++impl Component for MainComponent {+    fn connected(&self) {+        log!("Connected:", self.get_id());+    }++    fn disconnected(&self) {+        log!("Disconnected:", self.get_id());+    }++    fn attribute_changed(&self, name: &str, _old_value: &str, _new_value: &str) {+        if name == "test" {+            self.render();+        }+    }+}+```++## Rendering++Rendering can be done in `attribute_changed` but it is a separate function in thie example.++```rust+use kaja_web::prelude::*;++impl MainComponent {+    fn render(&self) {+        let test: bool = self.get_attribute("test").unwrap_or_default();++        let content = html! {{+            <p>Test: $test</p>+        }};++        let id = self.get_id();++        if let Some(element) = get_element_by_id(&id) {+            element.set_inner_html(content.as_str());+        } else {+            error!("Element not found for component id:", id);+        }+    }+}+```++## Startup++```rust+use kaja_web::prelude::*;++#[wasm_bindgen(start)]+pub fn init() {+    let elements = get_elements("main-component");+    +    for element in elements {+        let id = element.id();+    +        if id.is_empty() {+            continue;+        }+    +        if let Some(element) = get_element_by_id(&id) {+            let test = true;+            let _ = element.set_attribute("test", test.to_string().as_str());+        }+    }+}+```++## Usage++```html+<main-component test="false"></main-component>+```diff --git a/src/init.rs b/src/init.rsindex c8bbd34..23533e2 100644--- a/src/init.rs+++ b/src/init.rs@@ -614,6 +614,73 @@ fn create_component(struct_item: &ItemStruct) -> proc_macro2::TokenStream {             where                 T: ToString,             {+                <Self as ::kaja_web::ComponentHandle>::set_attribute(self, name, value)+            }++            fn set_attribute_string(&self, name: &str, value: &str) -> Result<()> {+                <Self as ::kaja_web::ComponentHandle>::set_attribute_string(self, name, value)+            }++            fn is_valid_attribute(&self, name: &str, value: &str) -> bool {+                let attr = self.attribute_values.borrow();++                if attr.validate_test_attribute(name, value).is_err() {+                    error!("Failed to parse attribute:", name, "with value:", value, "in set_attribute");+                    return false;+                }++                true+            }++            fn get_attribute_string(&self, name: &str) -> Option<String> {+                <Self as ::kaja_web::ComponentHandle>::get_attribute_string(self, name)+            }++            fn get_attribute<T>(&self, name: &str) -> Option<T>+            where+                T: std::str::FromStr,+            {+                <Self as ::kaja_web::ComponentHandle>::get_attribute(self, name)+            }++            fn get_attributes(&self) -> std::rc::Rc<std::cell::RefCell<#struct_ident>> {+                <Self as ::kaja_web::ComponentHandle>::get_attributes(self)+            }++            fn borrow(&self) -> std::cell::Ref<'_, #struct_ident> {+                <Self as ::kaja_web::ComponentHandle>::borrow(self)+            }++            fn borrow_mut(&self) -> std::cell::RefMut<'_, #struct_ident> {+                <Self as ::kaja_web::ComponentHandle>::borrow_mut(self)+            }++            fn with_mut<F>(&self, f: F)+            where+                F: FnOnce(&mut #struct_ident),+            {+                <Self as ::kaja_web::ComponentHandle>::with_mut(self, f)+            }++            fn with<F>(&self, f: F)+            where+                F: FnOnce(&#struct_ident),+            {+                <Self as ::kaja_web::ComponentHandle>::with(self, f)+            }++            fn get_id(&self) -> String {+                <Self as ::kaja_web::ComponentHandle>::get_id(self)+            }+        }++        impl ::kaja_web::ComponentHandle for #component_ident {+            type State = #struct_ident;++            fn set_attribute<T>(&self, name: &str, value: T) -> Result<()>+            where+                T: ToString,+            {                 let value = value.to_string();                 self.set_attribute_string(name, &value)             }@@ -649,17 +716,6 @@ fn create_component(struct_item: &ItemStruct) -> proc_macro2::TokenStream {                 Ok(())             } -            fn is_valid_attribute(&self, name: &str, value: &str) -> bool {-                let attr = self.attribute_values.borrow();--                if attr.validate_test_attribute(name, value).is_err() {-                    error!("Failed to parse attribute:", name, "with value:", value, "in set_attribute");-                    return false;-                }--                true-            }-             fn get_attribute_string(&self, name: &str) -> Option<String> {                 let attr = self.attribute_values.borrow();                 attr.get_attribute(name)

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112