Commit d955433
Documentation
Changed files (2)
Diff
new file mode 100644@@ -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>+```@@ -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)